﻿/*
 * CreatureCommonAI.cpp
 *
 *  Created on: 2017锟斤拷3锟斤拷20锟斤拷
 *      Author: gaoyi
 */

#include "CreatureCommonAI.h"
#include "Character/MovePart.h"
#include "Skill/SkillBase.h"
#include "Common/TableData/AreaPathCfg.h"
#include "Character/monster/MonsterRefCfg.h"

#include "Character/Player.h"
#include "ProtoBuffer/AllProtocol.h"
#include "Common/EventDefine.h"
#include "base/core/gamemath.h"
#include "Character/npc/Npc.h"

#include "base/core/Profiler.h"

#include "Character/CreatureMgr.h"
#include "Character/monster/MonsterMgr.h"
#include "Character/monster/MonsterRefMgr.h"

#include "Effect/EffectMgr.h"
#include "ServerModule/LogicEscortModule.h"

CreatureCommonAI::CreatureCommonAI()
{
	mAiInternalTime = 200;
	mAttackType = CreatureAttackType::CreatureAttackType_NOATTACK;
	mOwnerCid = 0;
	mTargetCid = 0;
}

CreatureCommonAI::~CreatureCommonAI()
{
}

bool CreatureCommonAI::Init(Creature* pMaster)
{
	mMaster = pMaster;
	g_GetEvent()->Subscribe(dynamic_cast<IEventExecuteSink*>(this), EVENT_UNDER_ATTACK, mMaster->GetCid(), 0, NULL);
	g_GetEvent()->Subscribe(dynamic_cast<IEventExecuteSink*>(this), EVENT_END_MOVE, mMaster->GetCid(), mMaster->CreatureKind(), NULL);
	g_GetEvent()->Subscribe(dynamic_cast<IEventExecuteSink*>(this), EVENT_HP_CHANGE, mMaster->GetCid(), 0, NULL);

	SetMasterAndInit(pMaster);

	if (pMaster->CreatureKind() == CREATURE_MONSTER)
	{
		Monster* pMonster = dynamic_cast<Monster*>(pMaster);
		if (pMonster)
		{
			if (pMonster->GetMonsterInfo()->bornEffectAIDelay > 0)
				g_GetTimerAxis()->SetTimer(AI_TIME_BORN_DELAYED, pMonster->GetMonsterInfo()->bornEffectAIDelay, this, 1);
			else
				g_GetTimerAxis()->SetTimer(AI_TIME_BORN_DELAYED, 1, this, 1);
		}
	}
	else
	{
		g_GetTimerAxis()->SetTimer(AI_TIME_BORN_DELAYED, 1, this, 1);
	}

	return true;
}

bool CreatureCommonAI::UnInit()
{
	g_GetTimerAxis()->KillAllTimer(this);
	g_GetEvent()->UnSubscribeAll(dynamic_cast<IEventExecuteSink*>(this));
	return true;
}

void CreatureCommonAI::OnTimer(uint32_t nTimerID)
{
	if (mMaster->IsDead())
	{
		return;
	}
	switch(nTimerID)
	{
	case AI_TIME_USE_SKILL:
	{
		OnHandleUseSkill();
	}
	break;
	case AI_TIME_REST_STATUS:
	{
		BEGIN_PROFILE("CreatureCommonAI::OnTimer");
		BEGIN_PROFILE("CreatureCommonAI::OnTimer::AI_TIME_REST_STATUS");
		OnHandleRestStatus();
		END_PROFILE();
		END_PROFILE();
	}
	break;
	case AI_TIME_PATROL_STATUS:
	{
		BEGIN_PROFILE("CreatureCommonAI::OnTimer");
		BEGIN_PROFILE("CreatureCommonAI::OnTimer::AI_TIME_PATROL_STATUS");
		OnHandlePatrolStatus();
		END_PROFILE();
		END_PROFILE();
	}
	break;
	case AI_TIME_AUTO_MONSTER_FIND_ENEMY:
	{
		BEGIN_PROFILE("CreatureCommonAI::OnTimer");
		BEGIN_PROFILE("CreatureCommonAI::OnTimer::AI_TIME_AUTO_MONSTER_FIND_ENEMY");
		OnHandleAutoMonsterFindEnemyAI();
		END_PROFILE();
		END_PROFILE();
	}
	break;
	case AI_TIME_COMBAT:
	{
		BEGIN_PROFILE("CreatureCommonAI::OnTimer");
		BEGIN_PROFILE("CreatureCommonAI::OnTimer::AI_TIME_COMBAT");
		OnHandleCombatStatus();
		END_PROFILE();
		END_PROFILE();
	}
	break;
	case AI_TIME_BORN_DELAYED:
	{
		if (mMaster->CreatureKind() == CREATURE_MONSTER)
		{
#ifdef AI_DEBUG
			Monster* pMonster = dynamic_cast<Monster*>(Master);
			if (pMonster)
			{
				StartTimerRestStatus();
			}
#else
			Monster* pMonster = dynamic_cast<Monster*>(mMaster);
			if (pMonster)
			{
				if (pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_SUMMON
						|| pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_MOVE_BIAOCHE_MONSTER
						|| pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_MOVE_BIAOCHE
						|| pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_MOVE_TEAM_BIAOCHE)
				{
					StartTimerCombatStatus();
					StartTimerAutoMonsterFindEnemyAI();
					return;
				}
				else if (pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_CAN_USE_THING
						|| pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_CAN_USE_DROP
						|| pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_CAN_DESTROYED_THING)
				{
					return;
				}
				else if (pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_CAN_TRIGGER_THING
						|| pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_CAN_TRAP
						|| pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_NO_MOVE_BOSS
						|| pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_BOSS_ZHONGSHEN
						|| pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_TRAP_CAN_BE_ATTATED)
				{
					g_GetEvent()->Subscribe(dynamic_cast<IEventExecuteSink*>(this), EVENT_MONSTER_BEEN_FIRST_PLAYER_SEE,mMaster->GetCid(),0, NULL);
					g_GetEvent()->Subscribe(dynamic_cast<IEventExecuteSink*>(this), EVENT_MONSTER_NO_PLAYER_SEE,mMaster->GetCid(),0, NULL);

					if (mIsAIWorkWhenNobody > 0)
					{
						g_GetEvent()->Subscribe(dynamic_cast<IEventExecuteSink*>(this), EVENT_SCENE_FIRST_PLAYER,mMaster->GetSceneId(),0, NULL);
						g_GetEvent()->Subscribe(dynamic_cast<IEventExecuteSink*>(this), EVENT_SCENE_NO_PLAYER,mMaster->GetSceneId(),0, NULL);

						if (pMonster->GetScene() && !pMonster->GetScene()->GetAllPlayerInScene()->empty())
						{
							StartTimerCombatStatus();
							return;
						}
					}

					if (mMaster->BeenSeeByPlayer())
					{
						StartTimerCombatStatus();
						return;
					}
				}
				else if (pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_MONSTER
						|| pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_TA)
				{
					g_GetEvent()->Subscribe(dynamic_cast<IEventExecuteSink*>(this), EVENT_MONSTER_BEEN_FIRST_PLAYER_SEE,mMaster->GetCid(),0, NULL);
					g_GetEvent()->Subscribe(dynamic_cast<IEventExecuteSink*>(this), EVENT_MONSTER_NO_PLAYER_SEE,mMaster->GetCid(),0, NULL);

					if (mIsAIWorkWhenNobody > 0)
					{
						g_GetEvent()->Subscribe(dynamic_cast<IEventExecuteSink*>(this), EVENT_SCENE_FIRST_PLAYER,mMaster->GetSceneId(),0, NULL);
						g_GetEvent()->Subscribe(dynamic_cast<IEventExecuteSink*>(this), EVENT_SCENE_NO_PLAYER,mMaster->GetSceneId(),0, NULL);

						if (pMonster->GetScene() && !pMonster->GetScene()->GetAllPlayerInScene()->empty())
						{
							StartTimerRestStatus();
							return;
						}
					}

					if (mMaster->BeenSeeByPlayer())
					{
						StartTimerRestStatus();
						return;
					}
				}
				else
				{
					LogDebugFmtPrint("AI_TIME_BORN_DELAYED Monster StartTimer Error!");
				}
			}
#endif
		}
		else if (mMaster->CreatureKind() == CREATURE_NPC)
		{
			g_GetEvent()->Subscribe(dynamic_cast<IEventExecuteSink*>(this), EVENT_MONSTER_BEEN_FIRST_PLAYER_SEE,mMaster->GetCid(),0, NULL);
			g_GetEvent()->Subscribe(dynamic_cast<IEventExecuteSink*>(this), EVENT_MONSTER_NO_PLAYER_SEE,mMaster->GetCid(),0, NULL);

			Npc* pNpc = dynamic_cast<Npc*>(mMaster);
			if (pNpc && mIsAIWorkWhenNobody > 0)
			{
				g_GetEvent()->Subscribe(dynamic_cast<IEventExecuteSink*>(this), EVENT_SCENE_FIRST_PLAYER,mMaster->GetSceneId(),0, NULL);
				g_GetEvent()->Subscribe(dynamic_cast<IEventExecuteSink*>(this), EVENT_SCENE_NO_PLAYER,mMaster->GetSceneId(),0, NULL);

				if (pNpc->GetScene() && !pNpc->GetScene()->GetAllPlayerInScene()->empty())
				{
					StartTimerCombatStatus();
					return;
				}
			}

			if (mMaster->BeenSeeByPlayer())
			{
				StartTimerCombatStatus();
				return;
			}
		}
		else if (mMaster->CreatureKind() == CREATURE_REBOT)
		{
			return;
		}
	}
	break;
	}
}

void CreatureCommonAI::OnExecute(uint16_t nEventID, uint64_t nSrcID, uint8_t bySrcType, void *pContext, int32_t nLen)
{
	if (mMaster->IsDead())
	{
		return;
	}
	switch (nEventID)
	{
	case EVENT_HP_CHANGE:
	{
		HandleCommonSpecialSkills();
	}
	break;
	case EVENT_END_MOVE:
	{
		if (mMaster->IsDead())
		{
			return;
		}
		if (mMaster->CreatureKind() == CREATURE_NPC)
		{
			if (IsInNpcTeam())
			{
				if (IsNpcTeamLeader())
				{
					if (mPatrolPath.IsReachNextPatrolPath() && mPatrolPath.GetNextPatrolPathIndex() == 0)
					{
						if (mNpcTeamId > 0)
						{
							g_GetGeneralCreatureRefMgr()->UpdateNpcTeamDead(mMaster->GetSceneId(), g_GetGlobalServerTime()->Tick(), mNpcTeamId);
						}
					}
					if (IsHateListEmpty() && !IsFightStatus())
					{
						MoveToNextPatrolPath();
					}
				}
				else
				{
					if (IsNpcTeamLeaderHateListEmpty() && !IsFightStatus() && !IsNpcTeamLeaderFightStats())
					{
						NpcTeamSetFollower();
						NpcTeamMoveToPatrolPath();
					}
				}
			}
		}

		if (mMaster->CreatureKind() == CREATURE_MONSTER)
		{
			Monster* pMonster = dynamic_cast<Monster*>(mMaster);
			if (pMonster)
			{
				if (GetIsStartTimer_Combat() == false && GetIsStartTimer_UseSkill() == false)
				{
					if (pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_MONSTER
							|| pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_TA)
					{
						if (mIsAIWorkWhenNobody > 0)
						{
							if (pMonster->GetScene() && !pMonster->GetScene()->GetAllPlayerInScene()->empty())
							{
								StartTimerRestStatus();
								return;
							}
						}

						if (mMaster->BeenSeeByPlayer())
						{
							StartTimerRestStatus();
							return;
						}
					}
				}
				else
				{
					OnHandleCombatStatus();
				}
			}
		}
	}
	break;
	case EVENT_UNDER_ATTACK:
	{
		MovePart *pMove = dynamic_cast<MovePart*>(mMaster->GetPart(PART_MOVE));
		if (pMove && pMove->IsMoving())
		{
			if ((IsMonsterNoAttackMonster() && HasPatrolPath()) == false)
			{
				mMaster->StopMove();
			}
		}

		skillAttackEvent  *pEvent = static_cast<skillAttackEvent*>(pContext);
		if (pEvent && mMaster->GetScene())
		{
			const SkillSkillCfgInfo *pSkillInfo = g_GetSkillSkillCfgTable()->GetSkillSkillCfgInfo(pEvent->skillId);
			Creature* pCreature = mMaster->GetScene()->GetCreature(pEvent->attacker);
			if (pCreature == nullptr || pCreature == mMaster)
			{
				break;
			}

			if (pCreature == nullptr || pCreature == mMaster)
			{
				break;
			}

			if (mMaster->CreatureKind() == CREATURE_MONSTER)
			{
				Monster* pMonster = dynamic_cast<Monster*>(mMaster);
				if (pMonster)
				{
					if (pCreature->CreatureKind() == CREATURE_PLAYER)
					{
						uint32_t damageValue = pEvent->sufferedValue;
						if ((uint32_t)mMaster->GetAttr(C_HP) < damageValue)
						{
							damageValue = mMaster->GetAttr(C_HP);
						}

						//怪物仇恨值唤醒
						if (pMonster->GetMonsterInfo()->wakeupRadius > 0 && GetHateList().IsEmpty())
						{
							std::list<CharIDType> clist;
							pMonster->GetScene()->FindCreatureInCircle(clist, pMonster->GetPos(), pMonster->GetMonsterInfo()->wakeupRadius / 1000.0f);
							for(auto it = clist.begin(); it != clist.end(); it++)
							{
								if (*it != pMonster->GetCid())
								{
									Creature* pWakeUpCreature = pMonster->GetScene()->GetCreature(*it);
									if (pWakeUpCreature &&
											pWakeUpCreature->CreatureKind() == CREATURE_MONSTER)
									{
										if (pWakeUpCreature->GetAiData() && pWakeUpCreature->GetAiData()->GetHateList().IsEmpty())
										{
											pWakeUpCreature->GetAiData()->AddHateTarget(pCreature->GetCid(), pSkillInfo->threat, damageValue);
										}
									}
								}
							}
						}

						AddHateTarget(pCreature->GetCid(), pSkillInfo->threat, damageValue);

					}
					else if (pCreature->CreatureKind() == CREATURE_MONSTER)
					{
						//使用物品仇恨给玩家
						Monster* pTarget = dynamic_cast<Monster*>(pCreature);
						if (pTarget && pTarget->GetParentMonsterType() == PARENT_MONSTER_TYPE_CAN_USE_THING)
						{
							uint32_t damageValue = pEvent->sufferedValue;
							if ((uint32_t)mMaster->GetAttr(C_HP) < damageValue)
							{
								damageValue = mMaster->GetAttr(C_HP);
							}

							AddHateTarget(pTarget->GetMonsterMasterCID(), pSkillInfo->threat, damageValue);
						}

						//召唤物仇恨继承
						if (pTarget && pTarget->GetParentMonsterType() == PARENT_MONSTER_TYPE_SUMMON)
						{
							if (pMonster && pMonster->GetAiData())
							{
								pMonster->GetAiData()->AddHateTarget(pTarget->GetMonsterMasterCID(), pSkillInfo->threat * pTarget->GetMonsterInfo()->hateLost / 1000.0f, 0);
								pMonster->GetAiData()->AddHateTarget(pTarget->GetCid(), pSkillInfo->threat, 0);
							}
						}
					}
				}

			}
			else if (mMaster->CreatureKind() == CREATURE_NPC)
			{
				if (pCreature->CreatureKind() == CREATURE_PLAYER
						|| pCreature->CreatureKind() == CREATURE_NPC
						|| pCreature->CreatureKind() == CREATURE_MONSTER)
				{
					uint32_t damageValue = pEvent->sufferedValue;
					if ((uint32_t)mMaster->GetAttr(C_HP) < damageValue)
					{
						damageValue = mMaster->GetAttr(C_HP);
					}

					//Npc* pNpc = dynamic_cast<Npc*>(Master);
					if (mNpcTeamId > 0)
					{
						//g_GetCreatureMgr()->NpcTeamSyncHate(NpcTeamId, pNpc, pCreature->GetCid(), pSkillInfo->threat);
					}
					else
					{
						AddHateTarget(pCreature->GetCid(), pSkillInfo->threat, damageValue);
					}
				}
			}
			else if (mMaster->CreatureKind() == CREATURE_REBOT)
			{
				if (pCreature->CreatureKind() == CREATURE_PLAYER)
				{
					uint32_t damageValue = pEvent->sufferedValue;
					if ((uint32_t)mMaster->GetAttr(C_HP) < damageValue)
					{
						damageValue = mMaster->GetAttr(C_HP);
					}

					AddHateTarget(pCreature->GetCid(), pSkillInfo->threat, damageValue);
					ClearHateListDeadAndSort();
				}
			}
		}
	}
	break;
	case EVENT_ACTIVITY_STOP:
	{
		ActivityStopEvent  *pEvent = static_cast<ActivityStopEvent*>(pContext);
		if (pEvent)
		{
			if (mMaster->CreatureKind() == CREATURE_MONSTER)
			{
				Monster* pMonster = dynamic_cast<Monster*>(mMaster);
				if (pMonster)
				{
					if (pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_NO_MOVE_BOSS)
					{
						const AiAiCfgInfo *pInfo = g_GetAiAiCfgTable()->GetAiAiCfgInfo(pMonster->GetMonsterInfo()->specialAI);
						if (pInfo)
						{
							std::vector<int> bossSkill;
							CommonApi::SplitStrToVecInt(pInfo->bossSkill, ",", &bossSkill);
							if (bossSkill.size() >= 2 && pEvent->activityId == (uint32_t)bossSkill[1])
							{
								this->mBossSpecial = true;
							}
						}
					}
				}
			}
		}
	}
	break;
	case EVENT_SCENE_FIRST_PLAYER:
	{
		if (mMaster->CreatureKind() == CREATURE_MONSTER)
		{
			Monster* pMonster = dynamic_cast<Monster*>(mMaster);
			if (pMonster)
			{
				if (pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_CAN_TRIGGER_THING
										|| pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_CAN_TRAP
										|| pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_NO_MOVE_BOSS)
				{
					if (mIsAIWorkWhenNobody > 0)
					{
						StartTimerCombatStatus();
					}
					return;
				}
				else if (pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_MONSTER
						|| pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_TA
						|| pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_BOSS_ZHONGSHEN)
				{
					if (mIsAIWorkWhenNobody > 0)
					{
						StartTimerRestStatus();
					}
				}
			}
		}
		else if (mMaster->CreatureKind() == CREATURE_NPC)
		{
			Npc* pNpc = dynamic_cast<Npc*>(mMaster);
			if (pNpc && mIsAIWorkWhenNobody > 0)
			{
				StartTimerCombatStatus();
			}
		}
	}
	break;
	case EVENT_SCENE_NO_PLAYER:
	{
		StopMove();
		KillAllTimerNoCombatStatus();
		StopTimerCombatStatus();
	}
	break;
	case EVENT_MONSTER_NO_PLAYER_SEE:
	{
		if (mMaster->CreatureKind() == CREATURE_MONSTER)
		{
			Monster* pMonster = dynamic_cast<Monster*>(mMaster);
			if (pMonster)
			{
				if (pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_CAN_TRIGGER_THING
										|| pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_CAN_TRAP
										|| pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_NO_MOVE_BOSS)
				{
					if (mIsAIWorkWhenNobody <= 0)
					{
						StopTimerCombatStatus();
						KillAllTimerNoCombatStatus();
					}
					return;
				}
				else if (pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_MONSTER
						|| pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_TA
						|| pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_BOSS_ZHONGSHEN)
				{
					if (mIsAIWorkWhenNobody <= 0 && !this->IsFightStatus())
					{
						StopTimerCombatStatus();
						KillAllTimerNoCombatStatus();
					}
				}
			}
		}
		else if (mMaster->CreatureKind() == CREATURE_NPC)
		{
			Npc* pNpc = dynamic_cast<Npc*>(mMaster);
			if (pNpc && mIsAIWorkWhenNobody <= 0)
			{
				StopTimerCombatStatus();
				KillAllTimerNoCombatStatus();
			}
		}
	}
	break;
	case EVENT_MONSTER_BEEN_FIRST_PLAYER_SEE:
	{
		if (mMaster->CreatureKind() == CREATURE_MONSTER)
		{
			Monster* pMonster = dynamic_cast<Monster*>(mMaster);
			if (pMonster)
			{
				if (pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_CAN_TRIGGER_THING
										|| pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_CAN_TRAP
										|| pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_NO_MOVE_BOSS
										|| pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_BOSS_ZHONGSHEN)
				{
					StartTimerCombatStatus();
				}
				else if (pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_MONSTER)
				{
					uint32_t num = Random(0, 100);
					if (num > 70)
					{
						StartTimerRestStatus();
					}
					else
					{
						StartTimerPatrolStatus();
					}
				}
				else if (pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_TA)
				{
					StartTimerRestStatus();
				}
			}
		}
		else if (mMaster->CreatureKind() == CREATURE_NPC)
		{
			StartTimerCombatStatus();
		}
	}
	break;
	default:
		break;
	}
}

BEGIN_PROPERTIES_DESCRIPTION(CreatureCommonAI)
{
	// CLASS_DISPLAYNAME(L"CreatureCommonAI");
	// CLASS_DESC(L"CreatureCommonAI");

	REGISTER_METHOD(TriggerHpStateOne);
	REGISTER_METHOD(TriggerHpStateTwo);
	REGISTER_METHOD(TriggerHpStateThree);
	REGISTER_METHOD(TriggerHpStateFour);

	REGISTER_METHOD(IsHpStateOneNeedTrigger);
	REGISTER_METHOD(IsHpStateTwoNeedTrigger);
	REGISTER_METHOD(IsHpStateThreeNeedTrigger);
	REGISTER_METHOD(IsHpStateFourNeedTrigger);

	REGISTER_METHOD(IsHpStateOneNoTrigger);
	REGISTER_METHOD(IsHpStateTwoNoTrigger);
	REGISTER_METHOD(IsHpStateThreeNoTrigger);
	REGISTER_METHOD(IsHpStateFourNoTrigger);

	REGISTER_METHOD(HasHpStateNoTrigger);
	REGISTER_METHOD(HasSpecialAI);
	REGISTER_METHOD(IsCurSkillNeedTarget);
	REGISTER_METHOD(IsTargetInViewRange);
	REGISTER_METHOD(IsTargetInThePursuitRange);
	REGISTER_METHOD(IsTargetInAttackRange);
	REGISTER_METHOD(IsMonsterAttackMonster);
	REGISTER_METHOD(HasActionRange);
	REGISTER_METHOD(HasHateListPlayer);
	REGISTER_METHOD(IsBeenSeeByPlayer);
	REGISTER_METHOD(HasPatrolPath);
	REGISTER_METHOD(HasRestWaitTime);
	REGISTER_METHOD(GetRestWaitTime);
	REGISTER_METHOD(IsTargetPosNoChange);
	REGISTER_METHOD(BroadcastPlayIdle);
	REGISTER_METHOD(MoveToNextPatrolPath);
	REGISTER_METHOD(MoveToNextRandomPos);
	REGISTER_METHOD(SetAttackTarget);
	REGISTER_METHOD(RemoveTarget);
	REGISTER_METHOD(SelectUsableSkill);
	REGISTER_METHOD(UseSkillToTarget);
	REGISTER_METHOD(ChangePursuitTargetPos);
	REGISTER_METHOD(PursuitTargetPos);
	REGISTER_METHOD(UseSkillNoTarget);
	REGISTER_METHOD(GoHome);
	REGISTER_METHOD(SetHome);
	REGISTER_METHOD(GetCurSkillEffectTime);
	REGISTER_METHOD(UpdateHateList);
	REGISTER_METHOD(IsHateListEmpty);
	REGISTER_METHOD(IsMonsterNoAttackMonster);
	REGISTER_METHOD(IsMonsterCanIdle);
	REGISTER_METHOD(HasOwnerCid);
	REGISTER_METHOD(HasUnionId);
	REGISTER_METHOD(HasCampId);
	REGISTER_METHOD(HasOwnerNearby);
	REGISTER_METHOD(HasUnionPlayerNearby);
	REGISTER_METHOD(IsPatrolFinish);
	REGISTER_METHOD(HasEnemyUnionPlayerNearby);
	REGISTER_METHOD(BiaoCheFinishPatrol);
	REGISTER_METHOD(UnionBiaoCheFinishPatrol);
	REGISTER_METHOD(StopMove);
	REGISTER_METHOD(StopAI);
	REGISTER_METHOD(FindNearestEnemy);
	REGISTER_METHOD(IsMonsterAutoAttack);
	REGISTER_METHOD(TriggerNearestEnemy);
	REGISTER_METHOD(KillSelf);
	REGISTER_METHOD(TrapTriggerEnemy);
	REGISTER_METHOD(IsTargetDead);
	REGISTER_METHOD(SetOwnerToTarget);
	REGISTER_METHOD(IsSummonNoBeAttacked);
	REGISTER_METHOD(NoBeAttackSummonUseSkill);
	REGISTER_METHOD(IsSummonNoMoved);
	REGISTER_METHOD(HasBiaoCheMonsterNearBy);
	REGISTER_METHOD(IsTargetInMinAttackRange);
	REGISTER_METHOD(FindNearestEnemyInScene);
	REGISTER_METHOD(IsFightStatus);
	REGISTER_METHOD(SetFightStatus);
	REGISTER_METHOD(ClearFightStatus);
	REGISTER_METHOD(UseMonsterTriggerEnemy);
	REGISTER_METHOD(IsNpcTeamLeader);
	REGISTER_METHOD(NpcTeamSetFollower);
	REGISTER_METHOD(IsInNpcTeam);
	REGISTER_METHOD(ChangePursuitFriendPos);
	REGISTER_METHOD(MoveSummonMove);
	REGISTER_METHOD(HasUseedSkill);
	REGISTER_METHOD(NoMoveBossTriggerNearestEnemy);
	REGISTER_METHOD(IsBossSpecialTrigger);
	REGISTER_METHOD(NoMoveBossUsingSpecialSkill);
	REGISTER_METHOD(GetHpPercent);
	REGISTER_METHOD(SelectSkillFindNearestEnemy);
	REGISTER_METHOD(ZhongShenBossMoveToSummon);
	REGISTER_METHOD(NpcTeamCountPatrolPos);
	REGISTER_METHOD(IsNeedTeamDictTooNear);
	REGISTER_METHOD(IsNeedTeamDictTooFar);
	REGISTER_METHOD(NpcTeamMoveToPatrolPath);
	REGISTER_METHOD(HasSummons);
	REGISTER_METHOD(IsNpcTeamLeaderHateListEmpty);
	REGISTER_METHOD(IsTargetInThePursuitRangeofNpcTeamLeader);
	REGISTER_METHOD(SetTeamAttackTarget);
	REGISTER_METHOD(RemoveTeamTarget);
	REGISTER_METHOD(IsNpcTeamLeaderFightStats);
	REGISTER_METHOD(TeamSetHome);
	REGISTER_METHOD(TeamGoHome);
	REGISTER_METHOD(ClearHateListOutOfThePursuitRange);
	REGISTER_METHOD(NpcTeamLeaderMoveToPatrolPath);
}
END_PROPERTIES_DESCRIPTION()

behaviac::EBTStatus CreatureCommonAI::TriggerHpStateOne()
{
	GetHpState().TriggerHpState(0);
	return behaviac::EBTStatus::BT_SUCCESS;
}

behaviac::EBTStatus CreatureCommonAI::TriggerHpStateTwo()
{
	GetHpState().TriggerHpState(1);
	return behaviac::EBTStatus::BT_SUCCESS;
}

behaviac::EBTStatus CreatureCommonAI::TriggerHpStateThree()
{
	GetHpState().TriggerHpState(2);
	return behaviac::EBTStatus::BT_SUCCESS;
}

behaviac::EBTStatus CreatureCommonAI::TriggerHpStateFour()
{
	GetHpState().TriggerHpState(3);
	return behaviac::EBTStatus::BT_SUCCESS;
}

bool CreatureCommonAI::IsHpStateOneNeedTrigger()
{
	return GetHpState().IsHpStateNeedTrigger(0);
}

bool CreatureCommonAI::IsHpStateTwoNeedTrigger()
{
	return GetHpState().IsHpStateNeedTrigger(1);
}

bool CreatureCommonAI::IsHpStateThreeNeedTrigger()
{
	return GetHpState().IsHpStateNeedTrigger(2);
}

bool CreatureCommonAI::IsHpStateFourNeedTrigger()
{
	return GetHpState().IsHpStateNeedTrigger(3);
}

bool CreatureCommonAI::IsHpStateOneNoTrigger()
{
	return GetHpState().IsHpStateNoTrigger(0);
}

bool CreatureCommonAI::IsHpStateTwoNoTrigger()
{
	return GetHpState().IsHpStateNoTrigger(1);
}

bool CreatureCommonAI::IsHpStateThreeNoTrigger()
{
	return GetHpState().IsHpStateNoTrigger(2);
}

bool CreatureCommonAI::IsHpStateFourNoTrigger()
{
	return GetHpState().IsHpStateNoTrigger(3);
}

bool CreatureCommonAI::HasHpStateNoTrigger()
{
	return GetHpState().HasHpStateNoTrigger();
}

bool CreatureCommonAI::HasSpecialAI()
{
	if (mSpecialAI > 0)
	{
		const AiAiCfgInfo *pInfo = g_GetAiAiCfgTable()->GetAiAiCfgInfo(mSpecialAI);
		if (pInfo != nullptr)
		{
			return true;
		}
	}
	return false;
}

bool CreatureCommonAI::IsCurSkillNeedTarget()
{
	SkillPart* pPart = dynamic_cast<SkillPart*>(mMaster->GetPart(PART_SKILL));
	if (pPart)
	{
		uint32_t skillId = GetCurSkillId();
		stSkillInfo* pSkill = pPart->GetSkillInfo(skillId);
		if (pSkill)
		{
			if (pSkill->_pSkillmeta && pSkill->_pSkillmeta->rangeType < Range_none_target)
			{
				return true;
			}
		}
	}
	return false;
}

bool CreatureCommonAI::IsTargetInViewRange()
{
	Creature* pTarget = GetTarget();
	if (pTarget)
	{
		float powDist = point2LengthSquare(mMaster->GetPos(), pTarget->GetPos());
		float viewDict = (float)(mMaster->GetSightRange());

		if (powDist < viewDict * viewDict)
		{
			return true;
		}
	}
	return false;
}

bool CreatureCommonAI::IsTargetInThePursuitRange()
{
	Creature* pTarget = GetTarget();
	if (pTarget && pTarget->IsDead() == false && pTarget->GetScene() == mMaster->GetScene())
	{
		if (IsBiaocheMonster())
		{
			return true;
		}
		float pursuitDict = (float)(mPursuitRange) / 1000.0f; //追锟斤拷锟斤拷锟斤拷
		float powDist = 0;

		if (IsSummonMonster() && mMaster->GetScene())
		{
			Creature* pOwner = mMaster->GetScene()->GetCreature(GetOwnerCid());
			if (pOwner)
			{
				powDist = point2LengthSquare(pOwner->GetPos(), pTarget->GetPos());
			}
		}
		else if (!HasPatrolPath())
		{
			powDist = point2LengthSquare(mBornPos, pTarget->GetPos());
		}
		else
		{
			powDist = point2LengthSquare(mHomePos, pTarget->GetPos());
		}

		if (powDist < pursuitDict * pursuitDict)
		{
			return true;
		}
	}
	return false;
}

bool CreatureCommonAI::IsTargetInAttackRange()
{
	Creature* pTarget = GetTarget();
	if (pTarget && pTarget->GetScene() == mMaster->GetScene())
	{
		uint32_t skillId = GetCurSkillId();
		float maxAttackDict = AiGetSkillMaxAttackDict(skillId); //锟斤拷锟斤拷锟斤拷锟斤拷
		maxAttackDict += pTarget->GetModelRadius();
		float powDist = point2LengthSquare(mMaster->GetPos(), pTarget->GetPos());
		if (powDist < maxAttackDict * maxAttackDict)
		{
			return true;
		}
	}
	return false;
}

bool CreatureCommonAI::IsTargetInMinAttackRange()
{
	Creature* pTarget = GetTarget();
	if (pTarget)
	{
		uint32_t skillId = GetCurSkillId();
		float maxAttackDict = AiGetSkillMinAttackDict(skillId); //锟斤拷锟斤拷锟斤拷锟斤拷
		float powDist = point2LengthSquare(mMaster->GetPos(), pTarget->GetPos());
		if (powDist < maxAttackDict * maxAttackDict)
		{
			return true;
		}
	}
	return false;
}

bool CreatureCommonAI::IsMonsterCanIdle()
{
	return IsMonsterNoAttackMonster() || IsHateListEmpty();
}

bool CreatureCommonAI::IsMonsterAutoAttack()
{
	return mAttackType == CreatureAttackType::CreatureAttackType_AUTOATTACK;
}

bool CreatureCommonAI::IsMonsterNoAttackMonster()
{
	return mAttackType == CreatureAttackType::CreatureAttackType_NOATTACK;
}

bool CreatureCommonAI::IsMonsterAttackMonster()
{
	return mAttackType != CreatureAttackType::CreatureAttackType_NOATTACK;
}

bool CreatureCommonAI::HasActionRange()
{
	if (mActiveRange > 0)
	{
		return true;
	}
	return false;
}

bool CreatureCommonAI::IsHateListEmpty()
{
	return mHateList.IsEmpty();
}

bool CreatureCommonAI::HasHateListPlayer()
{
	return mHateList.IsEmpty() == false;
}

bool CreatureCommonAI::IsBeenSeeByPlayer()
{
	return mMaster->BeenSeeByPlayer();
}

bool CreatureCommonAI::HasPatrolPath()
{
	return mPatrolPath.HasPatrolPath();
}

bool CreatureCommonAI::HasRestWaitTime()
{
	if (mMaster->CreatureKind() == CREATURE_MONSTER)
	{
		Monster* pMonster = dynamic_cast<Monster*>(mMaster);
		if (pMonster)
		{
			return pMonster->GetMonsterInfo()->restWaitTime > 0;
		}
	}
	return false;
}

bool CreatureCommonAI::IsTargetPosNoChange()
{
	Creature* pTarget = GetTarget();
	if (pTarget)
	{
		if (GetPursuitData().IsChange(pTarget->GetPos()) == false)
		{
			return true;
		}
	}
	return false;
}

float CreatureCommonAI::GetRestWaitTime()
{
	if (mMaster->CreatureKind() == CREATURE_MONSTER)
	{
		Monster* pMonster = dynamic_cast<Monster*>(mMaster);
		if (pMonster)
		{
			return (float)pMonster->GetMonsterInfo()->restWaitTime + 1.0f;
		}
	}
	return 1.0f;
}

float CreatureCommonAI::GetHpPercent()
{
	int curHp = mMaster->GetAttr(C_HP);
	int maxHp = mMaster->GetAttr(C_MAX_HP);
	if (maxHp > 0)
	{
		return ((float)curHp)/(float)maxHp;
	}
	return 0.0f;
}

float CreatureCommonAI::GetCurSkillEffectTime()
{
	float attackTime = 1.0f;
	int count = 0;
	const SkillSkillCfgInfo *pInfo = g_GetSkillSkillCfgTable()->GetSkillSkillCfgInfo(mCurSkillId);
//	if (m_pMaster->CreatureKind() == CREATURE_REBOT)
//	{
//		if (pInfo->skillType != 1 && pInfo->releaseType == 1) //不是普通攻击 瞬发技能
//		{
//			return pInfo->readyTime;
//		}
//	}

	while (pInfo && count <= 5)
	{
		attackTime += pInfo->attackTime;

		pInfo = g_GetSkillSkillCfgTable()->GetSkillSkillCfgInfo(pInfo->Relation);

		count++;
	}

	return attackTime;
}

behaviac::EBTStatus CreatureCommonAI::BroadcastPlayIdle()
{
//
//	AiPlayIdleInfo info;
//	info.set_cid(Master->GetCid());
//	Master->BroadCastData(LOGIC_TO_CLIENT_PLAY_IDLE, &info);
	return behaviac::EBTStatus::BT_SUCCESS;
}

bool CreatureCommonAI::IsMove()
{
	MovePart* part = dynamic_cast<MovePart*>(mMaster->GetPart(PART_MOVE));
	if (!part)
	{
		return false;
	}

	return part->IsMoving();
}

behaviac::EBTStatus CreatureCommonAI::NpcTeamMoveToPatrolPath()
{
	if (NpcTeamCountPatrolPos() == behaviac::EBTStatus::BT_FAILURE) return behaviac::EBTStatus::BT_SUCCESS;

	if (IsNeedTeamDictTooFar())
	{
		if (!AiLogicUtility::UtilFloatEqual(mMaster->GetSpeed(), mMoveSpeed*1.5f/1000.0f))
		{
			mMaster->StopMove();
			mMaster->SetSpeed(mMoveSpeed*1.5f/1000.0f,true);//not fight staus, move
		}
	}

	if (IsNeedTeamDictTooNear())
	{
		StopMove();
		if (!AiLogicUtility::UtilFloatEqual(mMaster->GetSpeed(), mMoveSpeed/1000.0f))
		{
			mMaster->SetSpeed(mMoveSpeed/1000.0f,true);//not fight staus, move
		}
		return behaviac::EBTStatus::BT_SUCCESS;
	}

	if (IsMove())
	{
		return behaviac::EBTStatus::BT_RUNNING;
	}
	else
	{
		if (mPatrolPath.IsFinish())
		{
			return behaviac::EBTStatus::BT_SUCCESS;
		}

		if (mPatrolPath.HasPatrolPath())
		{
			if (mPatrolPath.IsReachNextPatrolPath())
			{
				mPatrolPath.SetNextPatrolPath();
				if (!mPatrolPath.IsFinish())
				{
					if (mPatrolPath.MoveToNextPatrolPath() == false)
					{
						return behaviac::EBTStatus::BT_SUCCESS;
					}
					return behaviac::EBTStatus::BT_RUNNING;
				}
				return behaviac::EBTStatus::BT_SUCCESS;
			}
			else
			{
				if (mPatrolPath.MoveToNextPatrolPath() == false)
				{
					return behaviac::EBTStatus::BT_SUCCESS;
				}
				return behaviac::EBTStatus::BT_RUNNING;
			}
		}
	}
	return behaviac::EBTStatus::BT_FAILURE;
}

behaviac::EBTStatus CreatureCommonAI::NpcTeamLeaderMoveToPatrolPath()
{
	MasterMove();

	if (IsMove())
	{
		return behaviac::EBTStatus::BT_SUCCESS;
	}
	else
	{
		if (mPatrolPath.IsFinish())
		{
			return behaviac::EBTStatus::BT_SUCCESS;
		}

		if (mPatrolPath.HasPatrolPath())
		{
			if (mPatrolPath.IsReachNextPatrolPath())
			{
				mPatrolPath.SetNextPatrolPath();
				if (!mPatrolPath.IsFinish())
				{
					if (mPatrolPath.MoveToNextPatrolPath() == false)
					{
						LogDebugFmtPrint("CreatureCommonAI::MoveToNextPatrolPath Failed! MasterCid:%ld, ConfigID:%d, PathIndex:%d", mMaster->GetCid(), mMaster->GetConfigId(), mPatrolPath.GetNextPatrolPathIndex());
						return behaviac::EBTStatus::BT_SUCCESS;
					}
					return behaviac::EBTStatus::BT_SUCCESS;
				}
				return behaviac::EBTStatus::BT_SUCCESS;
			}
			else
			{
				if (mPatrolPath.MoveToNextPatrolPath() == false)
				{
					LogDebugFmtPrint("CreatureCommonAI::MoveToNextPatrolPath Failed! MasterCid:%ld, ConfigID:%d, PathIndex:%d", mMaster->GetCid(), mMaster->GetConfigId(), mPatrolPath.GetNextPatrolPathIndex());
					return behaviac::EBTStatus::BT_SUCCESS;
				}
				return behaviac::EBTStatus::BT_SUCCESS;
			}
		}
	}
	return behaviac::EBTStatus::BT_FAILURE;
}

behaviac::EBTStatus CreatureCommonAI::MoveToNextPatrolPath()
{
	MasterMove();

	if (IsMove())
	{
		return behaviac::EBTStatus::BT_RUNNING;
	}
	else
	{
		if (mPatrolPath.IsFinish())
		{
			if (mIsPatrolChangeAuto)
			{
				this->SetAttackType(CreatureAttackType_AUTOATTACK);
			}
			return behaviac::EBTStatus::BT_SUCCESS;
		}

		if (mPatrolPath.HasPatrolPath())
		{
			if (mPatrolPath.IsReachNextPatrolPath())
			{
				mPatrolPath.SetNextPatrolPath();
				if (!mPatrolPath.IsFinish())
				{
					if (mPatrolPath.MoveToNextPatrolPath() == false)
					{
						LogDebugFmtPrint("CreatureCommonAI::MoveToNextPatrolPath Failed! MasterCid:%ld, ConfigID:%d, PathIndex:%d", mMaster->GetCid(), mMaster->GetConfigId(), mPatrolPath.GetNextPatrolPathIndex());
						return behaviac::EBTStatus::BT_SUCCESS;
					}
					return behaviac::EBTStatus::BT_RUNNING;
				}
				else
				{
					if (mIsPatrolChangeAuto)
					{
						this->SetAttackType(CreatureAttackType_AUTOATTACK);
					}
				}
				return behaviac::EBTStatus::BT_SUCCESS;
			}
			else
			{
				if (mPatrolPath.MoveToNextPatrolPath() == false)
				{
					LogDebugFmtPrint("CreatureCommonAI::MoveToNextPatrolPath Failed! MasterCid:%ld, ConfigID:%d, PathIndex:%d", mMaster->GetCid(), mMaster->GetConfigId(), mPatrolPath.GetNextPatrolPathIndex());
					return behaviac::EBTStatus::BT_SUCCESS;
				}
				return behaviac::EBTStatus::BT_RUNNING;
			}
		}
	}
	return behaviac::EBTStatus::BT_FAILURE;
}

behaviac::EBTStatus CreatureCommonAI::MoveToNextRandomPos()
{
	MasterMove();
	if (mPatrolRandomPos.IsSetRandomTargetPos())
	{
		mPatrolRandomPos.SetRandomTargetPos();
	}

	MovePart* part = dynamic_cast<MovePart*>(mMaster->GetPart(PART_MOVE));
	if (part->IsMoving())
	{
		return behaviac::EBTStatus::BT_RUNNING;
	}
	else
	{
		if (mPatrolRandomPos.IsReachTargetPos())
		{
			mPatrolRandomPos.ReachTargetPos();
			if (mPatrolRandomPos.MoveToTargetPos() == false)
			{
				return behaviac::EBTStatus::BT_SUCCESS;
			}
			return behaviac::EBTStatus::BT_RUNNING;
		}
		else
		{
			if (mPatrolRandomPos.MoveToTargetPos() == false)
			{
				return behaviac::EBTStatus::BT_SUCCESS;
			}
			return behaviac::EBTStatus::BT_RUNNING;
		}
	}
}

behaviac::EBTStatus CreatureCommonAI::ClearHateListOutOfThePursuitRange()
{
	for(auto it = mHateList.GetHateList().begin(); it != mHateList.GetHateList().end(); )
	{
		Creature* pTarget = mMaster->GetScene()->GetCreature(it->m_hateTargetCid);
		if (pTarget && pTarget->IsDead() == false && pTarget->GetScene() == mMaster->GetScene())
		{
			if (IsBiaocheMonster())
			{
				it++;
				continue;
			}
			float pursuitDict = (float)(mPursuitRange) / 1000.0f; //追锟斤拷锟斤拷锟斤拷
			float powDist = 0;

			if (IsSummonMonster() && mMaster->GetScene())
			{
				Creature* pOwner = mMaster->GetScene()->GetCreature(GetOwnerCid());
				if (pOwner)
				{
					powDist = point2LengthSquare(pOwner->GetPos(), pTarget->GetPos());
				}
			}
			else if (!HasPatrolPath())
			{
				powDist = point2LengthSquare(mBornPos, pTarget->GetPos());
			}
			else
			{
				powDist = point2LengthSquare(mHomePos, pTarget->GetPos());
			}

			if (powDist < pursuitDict * pursuitDict)
			{
				it++;
				continue;
			}
		}

		it = mHateList.GetHateList().erase(it);
	}
	return behaviac::EBTStatus::BT_SUCCESS;
}

behaviac::EBTStatus  CreatureCommonAI::UpdateHateList()
{
	bool flag  = false;
	if (!IsHateListEmpty())
	{
		flag = true;
	}
	ClearHateListDeadAndSort();
	if (!IsHateListEmpty())
	{
		flag = false;
	}
	if (flag)
	{
		if (mMaster->CreatureKind() == CREATURE_MONSTER)
		{
			Monster* pMonster = dynamic_cast<Monster*>(mMaster);
			if (pMonster && !pMonster->GetMonsterInfo()->outFightTrigger.empty())
			{
				std::vector<int32_t> vec;
				CommonApi::SplitStrToVecInt(pMonster->GetMonsterInfo()->outFightTrigger, ",", &vec);
				for(auto it = vec.begin(); it != vec.end(); it++)
				{
					g_GetEffectMgr()->OnEffect(pMonster, (EffectIDType)*it);
				}
			}
		}
	}
	return behaviac::EBTStatus::BT_SUCCESS;
}

behaviac::EBTStatus CreatureCommonAI::SetAttackTarget()
{
	Creature* pTarget = GetMaster()->GetScene()->GetCreature(GetTargetCid());
	if (pTarget)
	{
		if (GetMaster()->ViewFliter(pTarget, 0))
		{
			SetTargetCid(0);
			pTarget = nullptr;
		}
	}

	if ((g_GetGlobalServerTime()->Tick() > mChangeTargetCidCdTime) || pTarget == nullptr || pTarget->IsDead())
	{
		mChangeTargetCidCdTime = g_GetGlobalServerTime()->Tick() + 2000;
		UpdateHateList();
		if (HasHateListPlayer())
		{
			SetTargetCid();
			MasterRun();
			return behaviac::EBTStatus::BT_SUCCESS;
		}
		else
		{
			SetTargetCid(0);
			return behaviac::EBTStatus::BT_FAILURE;
		}
	}

	return behaviac::EBTStatus::BT_SUCCESS;
}

behaviac::EBTStatus CreatureCommonAI::SetOwnerToTarget()
{
	mTargetCid = GetOwnerCid();
	return behaviac::EBTStatus::BT_SUCCESS;
}

void CreatureCommonAI::RemoveHateTarget(CharIDType targetCid)
{
	mHateList.RemoveHateTarget(targetCid);
}

void CreatureCommonAI::ClearHateListDeadAndSort()
{
	mHateList.ClearDeadAndInvisible();
	mHateList.SortHateList();
}

behaviac::EBTStatus	 CreatureCommonAI::RemoveTarget()
{
	RemoveHateTarget(mTargetCid);
	ClearHateListDeadAndSort();
	if (IsHateListEmpty())
	{
		if (mMaster->CreatureKind() == CREATURE_MONSTER)
		{
			Monster* pMonster = dynamic_cast<Monster*>(mMaster);
			if (pMonster && !pMonster->GetMonsterInfo()->outFightTrigger.empty())
			{
				std::vector<int32_t> vec;
				CommonApi::SplitStrToVecInt(pMonster->GetMonsterInfo()->outFightTrigger, ",", &vec);
				for(auto it = vec.begin(); it != vec.end(); it++)
				{
					g_GetEffectMgr()->OnEffect(pMonster, (EffectIDType)*it);
				}
			}
		}
	}
	mTargetCid = 0;
	return behaviac::EBTStatus::BT_SUCCESS;
}

bool CreatureCommonAI::HasUseedSkill()
{
	uint32_t skillId = AiGetNextSkillId();
	const SkillCfg* pCfg = g_GetSkillMgr()->GetSkillCfg(skillId);
	if (pCfg)
	{
		return true;
	}
	return false;
}

bool CreatureCommonAI::IsBossSpecialTrigger()
{
	return mBossSpecial;
}

behaviac::EBTStatus CreatureCommonAI::SelectUsableSkill()
{
	uint32_t skillId = AiGetNextSkillId();
	const SkillCfg* pCfg = g_GetSkillMgr()->GetSkillCfg(skillId);
	if (pCfg)
	{
		SetCurSkillId(skillId);
		return behaviac::EBTStatus::BT_SUCCESS;
	}
	//LogErrFmtPrint("CreatureCommonAI::SelectUsableSkill failed, monster:%d skillId:%d error!", m_pMaster->GetConfigId(), skillId);
	return behaviac::EBTStatus::BT_FAILURE;
}

behaviac::EBTStatus CreatureCommonAI::UseSkillToTarget()
{
	Creature* pTarget =GetTarget();
	if (pTarget)
	{
		uint32_t skillId = GetCurSkillId();
		if (IsCanUseSkill(skillId, pTarget))
		{
			StopMove();
			AiUseSkill(skillId, pTarget);
			StartTimerUseSkill(GetCurSkillEffectTime());
			return behaviac::EBTStatus::BT_SUCCESS;
		}
	}
	return behaviac::EBTStatus::BT_SUCCESS;
}

bool CreatureCommonAI::ComputeFollowPoint(int mapId, Creature* pTarget, float followRadius, Point3<float>& destPos)
{
	Point3<float> srcPos = mMaster->GetPos();
	Point3<float> targetPos = pTarget->GetPos();
	destPos = targetPos;
	float angle = AiLogicUtility::GetDotAngle(srcPos.z, srcPos.x, targetPos.z, targetPos.x);
	float fRadius = followRadius * (0.5f + AiLogicUtility::UtilRandomFloat(0.5));

	if (AiLogicUtility::UtilFloatEqualZero(mLastFollowAngle))
	{
		//对象之间的直线角度
		mLastFollowAngle = angle;
	}

	if (AiLogicUtility::UtilFloatEqualZero(mFollowAngleAdd))
	{
		mFollowAngleAdd = MMO_PI_4 * ( -1.0f + AiLogicUtility::UtilRandomFloat(2.0f));
	}

	for(int i = 0; i < 5; i++)
	{
		float fRandomAngle = mFollowAngleAdd;
		float fLastFollowAngle = mLastFollowAngle;

		//判断当前的角度是否和上一次一样，避免大角度切换跟随角度
		fRandomAngle = cosf(fLastFollowAngle) * cosf(angle) > 0 ? fRandomAngle : - fRandomAngle;
		float tempAngle = angle + fRandomAngle;

		float fRdDis_X = fRadius * cosf(tempAngle);
		float fRdDis_Z = fRadius * sinf(tempAngle);

		Point3<float> tempPos;
		tempPos.x = destPos.x - fRdDis_X;
		tempPos.z = destPos.z - fRdDis_Z;
		tempPos.y = destPos.y;
		Point3<float> chasePoint;

		if (AiLogicUtility::GetNearstPos(mapId, tempPos, chasePoint))
		{
			mLastFollowAngle = angle;
			mFollowAngleAdd = fRandomAngle;
			destPos = chasePoint;
			return true;
		}
		else
		{
			//区范围 -1.0~-0.5 && 0.5~1.0
			float InitRandom = (-1.0f + AiLogicUtility::UtilRandomFloat(2.0f));
			if (InitRandom < 0.5f && InitRandom > -0.5f)
			{
				InitRandom += InitRandom > 0 ? 0.5f : -0.5f;
			}

			InitRandom = (MMO_PI_4 / 4.0f) * InitRandom;
			while(::abs(fRandomAngle + InitRandom) > MMO_PI_4)
			{//调整跟随偏移角度
				float random = (-1.0f + AiLogicUtility::UtilRandomFloat(2.0f));
				if (random < 0.5f && random > -0.5f)
				{
					random += random > 0 ? 0.5f : -0.5f;
				}
				InitRandom = (MMO_PI_4 / 4.0f) * random;
			}
			mFollowAngleAdd = fRandomAngle + InitRandom;
		}
	}
	return false;
}

behaviac::EBTStatus CreatureCommonAI::ChangePursuitFriendPos()
{
	Creature* pTarget = GetTarget();
	if (pTarget)
	{
		Point3<float> randomPos;
		float fdict = point2Length(pTarget->GetPos(), mMaster->GetPos());

		if (mMaster->CreatureKind() == CREATURE_MONSTER && dynamic_cast<Monster*>(mMaster)->GetParentMonsterType() == PARENT_MONSTER_TYPE_SUMMON)
		{
			//ComputeFollowPoint(m_pMaster->GetMapId(), pTarget, 3, randomPos);
			randomPos = AiLogicUtility::GetPosInStraight(mMaster->GetMapId(), mMaster->GetPos(), pTarget->GetPos(), 3);
		}
		else
		{
			if (fdict >= 1.0f)
			{
				//ComputeFollowPoint(m_pMaster->GetMapId(), pTarget, 1, randomPos);
				randomPos = AiLogicUtility::GetPosInStraight(mMaster->GetMapId(), mMaster->GetPos(), pTarget->GetPos(), 1);
			}
			else
			{
				return behaviac::EBTStatus::BT_SUCCESS;
			}
		}

		if (randomPos == Point3<float>())
		{
			randomPos = pTarget->GetPos();
		}

		GetPursuitData().SetTargetPos(randomPos);
		GetPursuitData().SetTargetSrcPos(pTarget->GetPos());
		mMaster->MoveTo(randomPos);
		return behaviac::EBTStatus::BT_SUCCESS;
	}
	return behaviac::EBTStatus::BT_FAILURE;
}

bool CreatureCommonAI::GetTargetRange(Creature* pTarget, float& fMinDis, float& fMaxDis)
{
	uint32_t skillId = GetCurSkillId();

	float min = AiGetSkillMinAttackDict(skillId);
	float max = AiGetSkillMaxAttackDict(skillId);

	min = min < max ? min : max;
	max = min > max ? min : max;

	fMinDis = min;
	fMaxDis = max;

	fMinDis += pTarget->GetModelRadius();
	fMaxDis += pTarget->GetModelRadius();
	return true;
}

behaviac::EBTStatus CreatureCommonAI::ChangePursuitTargetPos()
{
	Creature* pTarget = GetTarget();
	if (pTarget)
	{
		float fdict = point2Length(pTarget->GetPos(), mMaster->GetPos());
		float minAttackDict;
		float maxAttackDict;
		GetTargetRange(pTarget, minAttackDict, maxAttackDict);

		if (fdict < maxAttackDict)
		{
			return behaviac::EBTStatus::BT_SUCCESS;
		}

		float angle = 0.0f;
		int area = 0;
		Point3<float> destPos = pTarget->GetPos();
		AiLogicUtility::GetDestAndAngle(mMaster, pTarget, destPos, angle, area);
		if (!AiLogicUtility::GetChasePoint(mMaster->GetMapId(), minAttackDict, maxAttackDict, pTarget->GetPos(), angle, destPos))
		{
			destPos = pTarget->GetPos();
		}

		GetPursuitData().SetTargetPos(destPos);
		GetPursuitData().SetTargetSrcPos(pTarget->GetPos());
		GetPursuitData().SetPursuitSkillId(mCurSkillId);
		mMaster->MoveTo(destPos);
		return behaviac::EBTStatus::BT_SUCCESS;
	}
	return behaviac::EBTStatus::BT_FAILURE;
}

behaviac::EBTStatus CreatureCommonAI::PursuitTargetPos()
{
	Creature* pTarget = GetTarget();
	if (pTarget)
	{
		if (this->IsTargetInAttackRange())
		{
			return behaviac::EBTStatus::BT_SUCCESS;
		}

		if (GetPursuitData().IsChange(pTarget->GetPos()) || GetPursuitData().IsSkillChange(mCurSkillId))
		{
			ChangePursuitTargetPos();
			return behaviac::EBTStatus::BT_RUNNING;
		}

		MovePart* part = dynamic_cast<MovePart*>(mMaster->GetPart(PART_MOVE));
		if (part->IsMoving())
		{
			//LogDebugFmtPrint("Moving");
			return behaviac::EBTStatus::BT_RUNNING;
		}
		else
		{
			if (GetPursuitData().IsReach())
			{
				return behaviac::EBTStatus::BT_SUCCESS;
			}
			else
			{
				if (mMaster->MoveTo(GetPursuitData().GetTargetPos()) == false)
				{
					//LogDebugFmtPrint("PursuitTargetPos: the monster:%d can't Moveto the Pos, the may be a bug!", m_pMaster->GetCid());
					return behaviac::EBTStatus::BT_SUCCESS;
				}
				return behaviac::EBTStatus::BT_RUNNING;
			}
		}
	}
	return behaviac::EBTStatus::BT_FAILURE;
}

behaviac::EBTStatus CreatureCommonAI::SetHome()
{
	//MasterMove();
	//StopMove();
	if (HasPatrolPath()) //路锟斤拷巡锟斤拷
	{
		if (mMaster->CreatureKind() == CREATURE_MONSTER)
		{
			Monster* pMonster = dynamic_cast<Monster*>(mMaster);
			if (pMonster)
			{
				if (mPatrolPath.GetPatrolType() == ENUM_MONSTER_PATROL_TYPE_ROUND_TRIP)
				{
					mHomePos = mPatrolPath.GetNeastPos(mMaster->GetPos());
				}
				else if (mPatrolPath.GetPatrolType() == ENUM_MONSTER_PATROL_TYPE_LOOP_TRIP)
				{
					mHomePos = mPatrolPath.GetNeastPos(mMaster->GetPos());
				}
				else if (mPatrolPath.GetPatrolType() == ENUM_MONSTER_PATROL_TYPE_ONE_WAY_TRIP)
				{
					if (mPatrolPath.IsFinish())
					{
						mHomePos = mPatrolPath.GetTargetPos();
					}
					else
					{
						mHomePos = mPatrolPath.GetNeastPos(mMaster->GetPos());
					}
				}
			}
		}
	}
	else if (HasActionRange()) //锟斤拷锟斤拷贫锟�
	{
		mHomePos = mPatrolRandomPos.GetLastTargetPos();
		if (mHomePos == Point3<float>())
		{
			//一锟斤拷小锟斤拷为0锟姐，锟斤拷氐锟斤拷锟绞嘉伙拷锟�
			mHomePos = mBornPos;
		}
	}
	else
	{
		mHomePos = mBornPos;
	}

	mMaster->AddBuffState(CREATURE_BUFF_STATE_WUDI);
	return behaviac::EBTStatus::BT_SUCCESS;
}

behaviac::EBTStatus CreatureCommonAI::GoHome()
{
	MovePart* part = dynamic_cast<MovePart*>(mMaster->GetPart(PART_MOVE));
	if (part->IsMoving())
	{
		return behaviac::EBTStatus::BT_RUNNING;
	}
	else
	{
		MasterRun();
		float dict = point2LengthSquare(mHomePos, mMaster->GetPos());

		if (dict < 0.1)
		{
			mMaster->RemoveBuffState(CREATURE_BUFF_STATE_WUDI);
			ResetMonsterState();

			if (mMaster->CreatureKind() == CREATURE_MONSTER)
			{
				Monster* pMonster = dynamic_cast<Monster*>(mMaster);
				if (pMonster)
				{
					if (pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_MONSTER
							|| pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_TA
							|| pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_BOSS_ZHONGSHEN)
					{
						if (pMonster->GetMonsterInfo()->isAIWorkWhenNobody <= 0 && mMaster->BeenSeeByPlayer())
						{
							StartTimerRestStatus();
						}
						else if (pMonster->GetMonsterInfo()->isAIWorkWhenNobody > 0 && mMaster->GetScene() && mMaster->GetScene()->GetAllPlayerInScene()->empty() == false)
						{
							StartTimerRestStatus();
						}
						StopTimerCombatStatus();
					}
				}
			}

			return behaviac::EBTStatus::BT_SUCCESS;
		}
		else
		{
			if (mMaster->MoveTo(mHomePos) == false)
			{
				mMaster->Teleporting(mHomePos);
			}
			return behaviac::EBTStatus::BT_RUNNING;
		}
	}
	return behaviac::EBTStatus::BT_FAILURE;
}

uint32_t CreatureCommonAI::GetMasterNormalSkillID()
{
	SkillPart* pPart = dynamic_cast<SkillPart*>(mMaster->GetPart(PART_SKILL));
	if (pPart)
	{
		return pPart->GetNormalSkillID();
	}
	return 0;
}

behaviac::EBTStatus CreatureCommonAI::UseSkillNoTarget()
{
	Creature* pTarget = GetTarget();
	uint32_t skillId = GetCurSkillId();
	if (IsCanUseSkill(skillId, nullptr))
	{
		AiUseNoSkill(skillId, pTarget);
		StartTimerUseSkill(GetCurSkillEffectTime());
	}
	return behaviac::EBTStatus::BT_SUCCESS;
}

Creature* CreatureCommonAI::GetTarget()
{
	Scene* pScene = mMaster->GetScene();
	if (pScene)
	{
		return pScene->GetCreature(mTargetCid);
	}
	return nullptr;
}

void CreatureCommonAI::SetTargetCid()
{
	if (mHateList.IsEmpty())
	{
		mTargetCid = 0;
	}
	else
	{
		mTargetCid = mHateList.GetHateList().front().m_hateTargetCid;
	}
}

bool CreatureCommonAI::IsCanUseSkill(uint32_t skillId, Creature* pTarget)
{
	SkillPart* pSKillPart = static_cast<SkillPart*>(mMaster->GetPart(PART_SKILL));
	if (pSKillPart)
	{
		stSkillInfo *pSkillInfo = pSKillPart->GetSkillInfo(skillId);
		if (!pSkillInfo)
		{
			return false;
		}

		std::vector<CharIDType> vec;
		if (pTarget)
		{
			vec.push_back(pTarget->GetCid());
		}

		if (pSKillPart->IsCanUseSkill(skillId, &vec))
		{
			return true;
		}
	}
	return false;
}

uint32_t CreatureCommonAI::GetMaxPrioritySkill(float minDictSquare)
{
	SkillPart* pSkillPart = dynamic_cast<SkillPart*>(mMaster->GetPart(PART_SKILL));
	if (pSkillPart == nullptr)
	{
		return 0;
	}

	int32_t priority = -1;
	uint32_t skillId = 0;
	//
	for (auto iter = pSkillPart->GetSkillInfo().begin(); iter != pSkillPart->GetSkillInfo().end(); iter++)
	{
		const stSkillInfo& info = iter->second;

		if (std::find(mSpeicalSkillIds.begin(), mSpeicalSkillIds.end(), info._Id) == mSpeicalSkillIds.end())
		{
			continue;
		}

		if (pSkillPart->IsPassiveSkill(info._pSkillmeta))
		{
			continue;
		}

		if (info.GetAILeftCDTime() > 0)
		{
			continue;
		}

		if ((int32_t)info._priority > priority)
		{
			float maxAttack = info._pSkillmeta->attackDis / 1000.0f;
			maxAttack = maxAttack * maxAttack;
			if (maxAttack > minDictSquare)
			{
				priority = (int32_t)info._priority;
				skillId = info._Id;
			}
		}
	}

	if (priority < mGourpPriority)
	{
		if (HasGroupSkills() && GroupSkillCanUse())
		{
			std::vector<uint32_t> vecSkillIds;
			for (auto iter = pSkillPart->GetSkillInfo().begin(); iter != pSkillPart->GetSkillInfo().end(); iter++)
			{
				const stSkillInfo& info = iter->second;

				if (std::find(mGroupSkillIds.begin(), mGroupSkillIds.end(), info._Id) == mGroupSkillIds.end())
				{
					continue;
				}

				if (info.GetAILeftCDTime() > 0)
				{
					continue;
				}

				if (pSkillPart->IsPassiveSkill(info._pSkillmeta))
				{
					continue;
				}

				float maxAttack = info._pSkillmeta->attackDis / 1000.0f;
				maxAttack = maxAttack * maxAttack;
				if (maxAttack > minDictSquare)
				{
					vecSkillIds.push_back(info._Id);
				}
			}

			if (vecSkillIds.size() > 0)
			{
				uint32_t index = Random(vecSkillIds.size());
				return vecSkillIds[index];
			}
		}
	}

	return skillId;
}

uint32_t CreatureCommonAI::GetMonsterNoNormalSkillID(float minDictSquare)
{
	SkillPart* pSkillPart = dynamic_cast<SkillPart*>(mMaster->GetPart(PART_SKILL));
	if (pSkillPart == nullptr)
	{
		return 0;
	}

	std::vector<uint32_t> vec;
	for (auto iter = pSkillPart->GetSkillInfo().begin(); iter != pSkillPart->GetSkillInfo().end(); iter++)
	{
		const stSkillInfo& info = iter->second;

		if (std::find(mSpeicalSkillIds.begin(), mSpeicalSkillIds.end(), info._Id) != mSpeicalSkillIds.end())
		{
			continue;
		}

		if (std::find(mGroupSkillIds.begin(), mGroupSkillIds.end(), info._Id) != mGroupSkillIds.end())
		{
			continue;
		}

		if (pSkillPart->IsPassiveSkill(info._pSkillmeta))
		{
			continue;
		}

		if (iter->second._pSkillmeta->skilltype != enSkillType_Nomal &&
				iter->second.GetAILeftCDTime() <= 0)
		{
			float maxAttack = info._pSkillmeta->attackDis / 1000.0f;
			maxAttack = maxAttack * maxAttack;
			if (maxAttack > minDictSquare)
			{
				vec.push_back(iter->first);
			}
		}
	}

	uint32_t skillId = 0;
	if (vec.size() > 0)
	{
		uint32_t index = Random(vec.size());
		skillId = vec[index];
	}
	return skillId;
}

uint32_t CreatureCommonAI::GetNormalSkillID(float minDictSquare)
{
	SkillPart* pSkillPart = dynamic_cast<SkillPart*>(mMaster->GetPart(PART_SKILL));
	if (pSkillPart == nullptr)
	{
		return 0;
	}

	std::vector<uint32_t> vec;
	for (auto iter = pSkillPart->GetSkillInfo().begin(); iter != pSkillPart->GetSkillInfo().end(); iter++)
	{
		const stSkillInfo& info = iter->second;

		if (std::find(mSpeicalSkillIds.begin(), mSpeicalSkillIds.end(), info._Id) != mSpeicalSkillIds.end())
		{
			continue;
		}

		if (std::find(mGroupSkillIds.begin(), mGroupSkillIds.end(), info._Id) != mGroupSkillIds.end())
		{
			continue;
		}

		if (pSkillPart->IsPassiveSkill(info._pSkillmeta))
		{
			continue;
		}

		if (iter->second._pSkillmeta->skilltype == enSkillType_Nomal &&
				iter->second.GetAILeftCDTime() <= 0)
		{
			float maxAttack = info._pSkillmeta->attackDis / 1000.0f;
			maxAttack = maxAttack * maxAttack;
			if (maxAttack > minDictSquare)
			{
				vec.push_back(iter->first);
			}
		}
	}

	uint32_t skillId = 0;
	if (vec.size() > 0)
	{
		uint32_t index = Random(vec.size());
		skillId = vec[index];
	}
	return skillId;
}

uint32_t  CreatureCommonAI::AiGetNextSkillId(float minDictSquare)
{
	SkillPart* pSkillPart = dynamic_cast<SkillPart*>(mMaster->GetPart(PART_SKILL));
	if (HasSpecialAI())
	{
		if (pSkillPart)
		{
			if (mUseSkillTime + 5000 > g_GetGlobalServerTime()->Tick())
			{
				return GetNormalSkillID(minDictSquare);
			}
			else
			{
				uint32_t skillId = GetMaxPrioritySkill(minDictSquare);
				if (skillId == 0)
				{
					uint32_t skillId = GetMonsterNoNormalSkillID(minDictSquare);
					if (skillId == 0)
					{
						return GetNormalSkillID(minDictSquare);
					}
					return skillId;
				}
				return skillId;
			}
		}
	}
	else
	{
		if (pSkillPart)
		{
			if (mUseSkillTime + 5000 > g_GetGlobalServerTime()->Tick())
			{
				return GetNormalSkillID(minDictSquare);
			}
			else
			{
				uint32_t skillId = GetMonsterNoNormalSkillID(minDictSquare);
				if (skillId == 0)
				{
					return GetNormalSkillID(minDictSquare);
				}
				return skillId;
			}
		}
	}

	return 0;
}

void CreatureCommonAI::AiUseSkill(uint32_t skillId, Creature* pTarget)
{
	SkillPart* pSKillPart = static_cast<SkillPart*>(mMaster->GetPart(PART_SKILL));
	if (pSKillPart)
	{
		stSkillInfo *pSkillInfo = pSKillPart->GetSkillInfo(skillId);
		if (pSkillInfo == nullptr)
		{
			return;
		}

		Point3<float> dir = mMaster->GetDir();
		std::vector<CharIDType> vec;
		if (pTarget)
		{
			Point3<float> face = pTarget->GetPos() - mMaster->GetPos();
			face.y = 0;
			float length = face.length();
			if (length != 0)
			{
				face = face / length;
				dir = face;
			}
			vec.push_back(pTarget->GetCid());
		}

		if (dir == Point3<float>())
		{
			if (pTarget)
			{
				dir = pTarget->GetDir();
			}
		}

		if (pTarget)
		{
			pTarget->SetDir(dir);
			pSKillPart->BeginCreatureUseSkill(pSkillInfo->_Id, vec, dir, pTarget->GetPos());
		}
		else
		{
			pSKillPart->BeginCreatureUseSkill(pSkillInfo->_Id, vec, dir, mMaster->GetPos());
		}

		if (std::find(mSpeicalSkillIds.begin(), mSpeicalSkillIds.end(), skillId) != mSpeicalSkillIds.end())
		{
			mUseSkillTime = g_GetGlobalServerTime()->Tick();
		}

		if (std::find(mGroupSkillIds.begin(), mGroupSkillIds.end(), skillId) != mGroupSkillIds.end())
		{
			mGroupCdTime = g_GetGlobalServerTime()->Tick();
		}
	}
}

void CreatureCommonAI::AiUseNoSkill(uint32_t skillId, Creature* pTarget)
{
	SkillPart* pSKillPart = static_cast<SkillPart*>(mMaster->GetPart(PART_SKILL));
	if (pSKillPart)
	{
		stSkillInfo *pSkillInfo = pSKillPart->GetSkillInfo(skillId);
		if (pSkillInfo == nullptr)
		{
			return;
		}

		std::vector<CharIDType> vec;
		Point3<float> dir = mMaster->GetDir();
		if (pTarget)
		{
			Point3<float> face = pTarget->GetPos() - mMaster->GetPos();
			face.y = 0;
			float length = face.length();
			if (length != 0)
			{
				face = face / length;
				dir = face;
			}
		}

		if (dir == Point3<float>())
		{
			if (pTarget)
			{
				dir = pTarget->GetDir();
			}
		}

		if (pTarget)
		{
			pSKillPart->BeginCreatureUseSkill(pSkillInfo->_Id, vec, dir, pTarget->GetPos());
		}
		else
		{
			pSKillPart->BeginCreatureUseSkill(pSkillInfo->_Id, vec, dir, mMaster->GetPos());
		}

		if (std::find(mSpeicalSkillIds.begin(), mSpeicalSkillIds.end(), skillId) != mSpeicalSkillIds.end())
		{
			mUseSkillTime = g_GetGlobalServerTime()->Tick();
		}

		if (std::find(mGroupSkillIds.begin(), mGroupSkillIds.end(), skillId) != mGroupSkillIds.end())
		{
			mGroupCdTime = g_GetGlobalServerTime()->Tick();
		}
	}
}

float CreatureCommonAI::AiGetSkillMinAttackDict(uint32_t skillId)
{
	SkillPart* pSKillPart = static_cast<SkillPart*>(mMaster->GetPart(PART_SKILL));
	if (pSKillPart)
	{
		return pSKillPart->GetMinAttack(skillId) / 1000.0f;
	}
	return 0.0f;
}

float CreatureCommonAI::AiGetSkillMaxAttackDict(uint32_t skillId)
{
	SkillPart* pSKillPart = static_cast<SkillPart*>(mMaster->GetPart(PART_SKILL));
	if (pSKillPart)
	{
		return pSKillPart->GetMaxAttack(skillId) / 1000.0f;
	}
	return 0.0f;
}

void CreatureCommonAI::EnterScene(Scene* pScene, const Point3<float>& pos)
{
	ClearHateList();
	mTargetCid = 0;
	mCurSkillId = 0;
	if (mMaster->CreatureKind() == CREATURE_REBOT)
	{
			mBornPos = pos;
			mHomePos = pos;

			mPatrolRandomPos.SetHomePos(mHomePos);
			mPatrolRandomPos.SetLastTargetPos(mHomePos);
	}
}

void CreatureCommonAI::SetMasterAndInit(Creature* pMaster)
{
	mMaster = pMaster;
	mPatrolPath.SetMaster(pMaster);
	mHateList.SetMaster(pMaster);
	mPatrolRandomPos.SetMaster(pMaster);
	mPursuitData.SetMaster(pMaster);
	mHpState.SetMaster(pMaster);

	mBornPos = mMaster->GetPos();
	mHomePos = mMaster->GetPos();
	mActiveRange = 0;
	mPursuitRange = 0;
	mMoveSpeed = mMaster->GetSpeed() * 1000;
	mRunSpeed = mMaster->GetSpeed() * 1000;
	mSpecialAI = 0;
	mAiInternalTime = 200;

	mPatrolRandomPos.SetHomePos(mHomePos);
	mPatrolRandomPos.SetActiveRange(mActiveRange);
	mPatrolRandomPos.SetLastTargetPos(mHomePos);

	if (mMaster->CreatureKind() == CREATURE_MONSTER)
	{
		Monster* pMonster = dynamic_cast<Monster*>(mMaster);
		if (pMonster)
		{
			mBornPos = pMonster->GetBornPos();
			mHomePos = pMonster->GetBornPos();
			mActiveRange = pMonster->GetMonsterInfo()->actionRange;
			mPursuitRange = pMonster->GetMonsterInfo()->pursueRange;
			mMoveSpeed = pMonster->GetMonsterInfo()->mSpeed;
			mRunSpeed = pMonster->GetMonsterInfo()->rSpeed;
			mIsAIWorkWhenNobody = pMonster->GetMonsterInfo()->isAIWorkWhenNobody;

			mPatrolRandomPos.SetHomePos(mHomePos);
			mPatrolRandomPos.SetActiveRange(mActiveRange);
			mPatrolRandomPos.SetLastTargetPos(mHomePos);
			mSpecialAI = (uint32_t)pMonster->GetMonsterInfo()->specialAI;
			if (pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_SUMMON)
			{
				if (pMonster->GetMonsterFightType() == SUMMON_MONSTER_TYPE_CAN_BEATTACK_CAN_MOVE
						|| pMonster->GetMonsterFightType() == SUMMON_MONSTER_TYPE_CAN_BEATTACK_CANNOT_MOVE)
				{
					mAttackType = CreatureAttackType::CreatureAttackType_AUTOATTACK;
				}
				else
				{
					mAttackType = CreatureAttackType::CreatureAttackType_NOATTACK;
				}
			}
			else if (pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_CAN_TRIGGER_THING)
			{
				mAttackType = CreatureAttackType::CreatureAttackType_BEATTACKEDATTACK;
			}
			else if (pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_CAN_TRAP)
			{
				mAttackType = CreatureAttackType::CreatureAttackType_BEATTACKEDATTACK;
			}
			else
			{
				mAttackType = pMonster->GetMonsterFightType();
			}

			mOwnerCid = pMonster->GetMonsterMasterCID();
			mUnionId = pMonster->GetMonsterUnionID();
			mCampId = pMonster->GetMonsterCampID();

			uint32_t pathId = pMonster->GetMonsterInfo()->patrolPath;
			if (pathId > 0)
			{
				const PathRefLocation* pathLoc = g_GetMapLocationCfg()->GetPathRefLoc(pathId);
				if (pathLoc)
				{
					mPatrolPath.AddPatrolPath(pathLoc->m_vecPos, pMonster->GetMonsterInfo()->patrolType);
				}
				else
				{
					const AreaPathCfgInfo *pCfgInfo = g_GetAreaPathCfgTable()->GetAreaPathCfgInfo(pMonster->GetMonsterInfo()->patrolPath);
					if (pCfgInfo)
					{
					}
				}
			}
		}
	}
	else if (mMaster->CreatureKind() == CREATURE_NPC)
	{
		Npc* pNpc = dynamic_cast<Npc*>(mMaster);
		if (pNpc && pNpc->GetBattleInfo())
		{
			mBornPos = pNpc->GetBornPos();
			mHomePos = pNpc->GetBornPos();
			mActiveRange = pNpc->GetBattleInfo()->actionRange;
			mPursuitRange = pNpc->GetBattleInfo()->pursueRange;
			mMoveSpeed = pNpc->GetBattleInfo()->mSpeed;
			mRunSpeed = pNpc->GetBattleInfo()->rSpeed;

			mPatrolRandomPos.SetHomePos(mHomePos);
			mPatrolRandomPos.SetActiveRange(mActiveRange);
			mPatrolRandomPos.SetLastTargetPos(mHomePos);
			mSpecialAI = (uint32_t)pNpc->GetBattleInfo()->specialAI;
			mIsAIWorkWhenNobody = pNpc->GetBattleInfo()->isAIWorkWhenNobody;
			mNpcTeamId = pNpc->GetBattleInfo()->npcTeam;

			mAttackType = CreatureAttackType::CreatureAttackType_AUTOATTACK;

			uint32_t pathId = pNpc->GetBattleInfo()->patrolPath;
			if (pathId > 0)
			{
				const PathRefLocation* pathLoc = g_GetMapLocationCfg()->GetPathRefLoc(pathId);
				if (pathLoc)
				{
					mPatrolPath.AddPatrolPath(pathLoc->m_vecPos, pNpc->GetBattleInfo()->patrolType);
				}
			}
		}
	}
	else if (mMaster->CreatureKind() == CREATURE_REBOT)
	{
			mBornPos = mMaster->GetPos();
			mHomePos = mMaster->GetPos();
			mActiveRange = 10000 * 1000; //全锟斤拷图
			mPursuitRange = 10000 * 1000; //全锟斤拷图
			mMoveSpeed = mMaster->GetAttr(C_MSPEED);
			mRunSpeed = mMaster->GetAttr(C_MSPEED);

			mPatrolRandomPos.SetHomePos(mHomePos);
			mPatrolRandomPos.SetActiveRange(mActiveRange);
			mPatrolRandomPos.SetLastTargetPos(mHomePos);

			mAiInternalTime = 100;
			mSpecialAI = 0;
			mAttackType = CreatureAttackType::CreatureAttackType_AUTOATTACK;
	}

	if (mSpecialAI > 0)
	{
		const AiAiCfgInfo *pInfo = g_GetAiAiCfgTable()->GetAiAiCfgInfo(mSpecialAI);
		if (pInfo != nullptr)
		{
			for(int i = 0; i < (int)pInfo->vecAiAiConditionCfg.size(); i++)
			{
				HpStateInfo state;
				state.CopyFrom(pInfo->vecAiAiHpPeriodCfg[i]);
				mHpState.vecState.push_back(state);
			}
			mHpState.ComputeAllTrigger();

			std::vector<int> initSkill;
			CommonApi::SplitStrToVecInt(pInfo->initSkills, ",", &initSkill);
			if (initSkill.size() > 0 && initSkill.size() % 3 == 0)
			{
				for (uint32_t i = 0; i < initSkill.size(); i+=3)
				{
					int skillId = initSkill[i];
					mSpeicalSkillIds.push_back(skillId);
				}
			}

			for(int i = 0; i < (int)pInfo->vecAiAiHpPeriodCfg.size(); i++)
			{
				std::vector<int> vec;
				CommonApi::SplitStrToVecInt(pInfo->vecAiAiHpPeriodCfg[i].AddSkills, ",", &vec);
				if (vec.size() > 0 && vec.size() % 3 == 0)
				{
					for (uint32_t j = 0; j < vec.size(); j+=3)
					{
						int skillId = vec[j];
						mSpeicalSkillIds.push_back(skillId);
					}
				}
			}

			std::vector<int32_t> groupVec;
			if (!pInfo->randomSklGroup.empty())
			{
				CommonApi::SplitStrToVecInt(pInfo->randomSklGroup,",", &groupVec);
				for(int i = 0; i < (int)groupVec.size(); i++)
				{
					mGroupSkillIds.push_back(groupVec[i]);
				}
				mGroupCdInternal = pInfo->groupCD;
				mGourpPriority = pInfo->groupPriority;
			}
		}
	}

	mAiEnable = true;
}

void CreatureCommonAI::SetAllSkillsCds()
{
	SkillPart* pSkillPart = dynamic_cast<SkillPart*>(mMaster->GetPart(PART_SKILL));
	if (pSkillPart)
	{
		std::unordered_map<uint32_t, stSkillInfo>& pSkillInfo = pSkillPart->GetSkillInfo();
		std::unordered_map<uint32_t, stSkillInfo>::iterator it = pSkillInfo.begin();
		for (; it != pSkillInfo.end(); it++)
		{
			if (it->second._pSkillmeta->skilltype == enSkillType_Nomal)
			{
				continue;
			}

			it->second._cdTimeStamps = Time::Now().UnixMSec();
		}
	}
}

void CreatureCommonAI::ResetAllSkills()
{
	SkillPart* pSkillPart = dynamic_cast<SkillPart*>(mMaster->GetPart(PART_SKILL));
	if (pSkillPart)
	{
		if (mMaster->CreatureKind() == CREATURE_MONSTER)
		{
			Monster* pMonster = dynamic_cast<Monster*>(mMaster);
			if (pMonster)
			{
				const AiAiCfgInfo *pInfo = g_GetAiAiCfgTable()->GetAiAiCfgInfo(pMonster->GetMonsterInfo()->specialAI);
				if (pInfo)
				{
					std::vector<uint32_t> vecHpAddSkills;
					for(int i = 0; i < (int)pInfo->vecAiAiHpPeriodCfg.size(); i++)
					{
						std::vector<int> vecHpSkills;
						CommonApi::SplitStrToVecInt(pInfo->vecAiAiHpPeriodCfg[i].AddSkills, ",", &vecHpSkills);
						for(int i = 0; i < (int)vecHpSkills.size(); i += 3)
						{
							vecHpAddSkills.push_back(vecHpSkills[i]);
						}
					}

					std::vector<uint32_t> removeSkills;
					auto& pSkillInfo = pSkillPart->GetSkillInfo();
					auto it = pSkillInfo.begin();
					for (; it != pSkillInfo.end(); it++)
					{
						it->second._cdTimeStamps = 0;

						uint32_t skillId = it->first;

						if (std::find(vecHpAddSkills.begin(), vecHpAddSkills.end(), skillId) == vecHpAddSkills.end())
						{
							continue;
						}

						removeSkills.push_back(skillId);
					}

					for (size_t i = 0; i < removeSkills.size(); i++)
					{
						pSkillPart->RemoveSkill(removeSkills[i],false);
					}

					std::vector<int> initSkill;
					CommonApi::SplitStrToVecInt(pInfo->initSkills, ",", &initSkill);
					if (initSkill.size() > 0 && initSkill.size() % 3 == 0)
					{
						for (uint32_t i = 0; i < initSkill.size(); i += 3)
						{
							int skillId = initSkill[i];
							int priority = initSkill[i + 1];
							int time = initSkill[i + 1];
							if (pSkillPart->GetSkillInfo(skillId) == nullptr)
								pSkillPart->AddSkill(skillId, 1, 0, priority,false,false);

							stSkillInfo* pSkillInfo = pSkillPart->GetSkillInfo(skillId);
							if (pSkillInfo)
							{
								pSkillInfo->_cdTimeStamps = Time::Now().UnixMSec() - pSkillInfo->_pSkillmeta->cd + time;
							}
						}
					}
				}
			}
		}
	}
}

void CreatureCommonAI::ResetMonsterState()
{
	mUseSkillTime = 0;
	ClearHateList();
	ResetAllSkills();

	mMaster->SetAttr(C_HP, mMaster->GetAttr(C_MAX_HP), true);
	mMaster->SetAttr(C_MP, mMaster->GetAttr(C_MAX_MP), true);
	mHpState.Clear();
	ResetMonsterHateList();
	SetAllSkillsCds();
}

void CreatureCommonAI::ResetMonsterHateList()
{
	Scene* pScene = mMaster->GetScene();
	if (pScene == nullptr)
	{
		return;
	}
}

void CreatureCommonAI::MasterRun()
{
	if (!GetRunStatus())
	{
		StopMove();
		mMaster->SetSpeed(mRunSpeed/1000.0f,true);//fight staus, run
		SetRunStatus(true);
	}
}

void CreatureCommonAI::MasterMove()
{
	if (GetRunStatus())
	{
		StopMove();
		mMaster->SetSpeed(mMoveSpeed/1000.0f,true);//not fight staus, move
		SetRunStatus(false);
	}
}

bool CreatureCommonAI::HasOwnerCid()
{
	return mOwnerCid > 0;
}

bool CreatureCommonAI::HasUnionId()
{
	return mUnionId > 0;
}

bool CreatureCommonAI::HasCampId()
{
	return mCampId > 0;
}

bool CreatureCommonAI::HasBiaoCheMonsterNearBy()
{
	Scene* pScene = mMaster->GetScene();
	if (pScene == nullptr)
	{
		return false;
	}

	for(auto iter = mHateList.GetHateList().begin(); iter != mHateList.GetHateList().end(); iter++)
	{
		CharIDType cid = iter->m_hateTargetCid;
		Creature* pTarget = pScene->GetCreature(cid);
		if (pTarget && !pTarget->IsDead() && pTarget->CreatureKind() == CREATURE_MONSTER)
		{
			Monster* pMonster = dynamic_cast<Monster*>(pTarget);
			if (pMonster && pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_MOVE_BIAOCHE_MONSTER)
			{
				float dict = point2LengthSquare(pMonster->GetPos(), mMaster->GetPos());
				if (dict < mMaster->GetSightRange() * mMaster->GetSightRange())
				{
					return true;
				}
			}
		}
	}

	return false;
}

bool CreatureCommonAI::HasOwnerNearby()
{
	Scene* pScene = mMaster->GetScene();
	if (pScene)
	{
		std::list<CharIDType> seeLst;
		mMaster->FindCreatureInScene(seeLst);
		for (auto it = seeLst.begin(); it != seeLst.end(); it++)
		{
			CharIDType cid = *it;
			if (cid == mOwnerCid)
			{
				Creature* pOwner = pScene->GetCreature(mOwnerCid);
				if (pOwner && pOwner->GetCanBeSeenFlag())
				{
					int dict = point2LengthSquare(mMaster->GetPos(), pOwner->GetPos());
					if (dict < mMaster->GetSightRange()*mMaster->GetSightRange())
					{
						return true;
					}
				}
			}
		}
	}
	return false;
}

bool CreatureCommonAI::HasUnionPlayerNearby()
{
	Scene* pScene = mMaster->GetScene();
	if (pScene)
	{
		std::list<CharIDType> seeLst;
		mMaster->FindCreatureInScene(seeLst);
		for (auto it = seeLst.begin(); it != seeLst.end(); it++)
		{
			CharIDType cid = *it;
			Creature* pCreature = pScene->GetCreature(cid);
			if (pCreature && pCreature->CreatureKind() == CREATURE_PLAYER)
			{
				Player* pPlayer = dynamic_cast<Player*>(pCreature);
				if (pPlayer && (int32_t)pPlayer->GetAttr(C_UNION_ID) == (int32_t)mUnionId && pPlayer->GetCanBeSeenFlag())
				{
					int dict = point2LengthSquare(mMaster->GetPos(), pPlayer->GetPos());
					if (dict < mMaster->GetSightRange()*mMaster->GetSightRange())
					{
						/*UnionEscortMoveState unionBiaoChe;
						unionBiaoChe.escort_cid = mMaster->GetCid();
						unionBiaoChe.char_id = pPlayer->GetCid();
						unionBiaoChe.scene_id = mMaster->GetSceneId();
						unionBiaoChe.isMove = true;
						g_GetEvent()->FireExecute(EVENT_UNION_BIAOCHE_MOVE_STATE, 0, CREATURE_MONSTER, &unionBiaoChe, sizeof(unionBiaoChe));*/
						g_GetGEscortMgr()->OnEscortMove(mMaster, pPlayer->GetCid(), true);
						return true;
					}
				}
			}
		}
	}
	/*UnionEscortMoveState uBiaoChe;
	uBiaoChe.escort_cid = mMaster->GetCid();
	uBiaoChe.char_id = 0;
	uBiaoChe.scene_id = mMaster->GetSceneId();
	uBiaoChe.isMove = false;
	g_GetEvent()->FireExecute(EVENT_UNION_BIAOCHE_MOVE_STATE, 0, CREATURE_MONSTER, &uBiaoChe, sizeof(uBiaoChe));*/
	g_GetGEscortMgr()->OnEscortMove(mMaster, 0, false);
	return false;
}

bool CreatureCommonAI::HasEnemyUnionPlayerNearby()
{
	return false;
// 	Scene* pScene = mMaster->GetScene();
// 	if (pScene)
// 	{
// 		const MapMapCfgInfo *pMapInfo = g_GetMapMapCfgTable()->GetMapMapCfgInfo(mMaster->GetMapId());
// 		if (pMapInfo == nullptr)
// 		{
// 			return false;
// 		}
// 
// 		//安全区 不能攻击公会镖车
// 		if (pMapInfo->mapPk == MAP_PK_RULE_CAN_NOT_PK || !mMaster->IsCanBeAttackByCurrentPos())
// 		{
// 			return false;
// 		}
// 
// 		std::list<CharIDType> seeLst;
// 		mMaster->FindCreatureInScene(seeLst);
// 		for (auto it = seeLst.begin(); it != seeLst.end(); it++)
// 		{
// 			CharIDType cid = *it;
// 			Creature* pCreature = pScene->GetCreature(cid);
// 			if (pCreature && pCreature->CreatureKind() == CREATURE_PLAYER)
// 			{
// 				Player* pPlayer = dynamic_cast<Player*>(pCreature);
// 				if (pPlayer && !pPlayer->IsDead() && (int32_t)pPlayer->GetAttr(C_UNION_ID) != (int32_t)mUnionId)
// 				{
// 					int dict = point2LengthSquare(mMaster->GetPos(), pPlayer->GetPos());
// 					if (dict < mMaster->GetSightRange()*mMaster->GetSightRange())
// 					{
// 						g_GetGEscortMgr()->OnEscortEnemyStandBy(mMaster);
// 						return true;
// 					}
// 				}
// 			}
// 		}
// 	}
// 	return false;
}

bool CreatureCommonAI::IsPatrolFinish()
{
	return mPatrolPath.IsFinish();
}

//这里是镖车用的，指的是镖车怪所属镖车死亡，怪物死亡
bool CreatureCommonAI::IsTargetDead()
{
	Scene* pScene = mMaster->GetScene();
	if (pScene == nullptr) return true;

	bool flag = false;
	for(auto it = mHateList.GetHateList().begin(); it != mHateList.GetHateList().end(); it++)
	{
		HateTargetData& targetData = *it;
		Creature* pTarget = pScene->GetCreature(targetData.m_hateTargetCid);
		if (pTarget)
		{
			if (pTarget->CreatureKind() == CREATURE_MONSTER)
			{
				flag = true;
				if (pTarget->IsDead())
				{
					return true;
				}
			}
		}
	}

	if (flag)
	{
		return false;
	}
	return true;
}

bool CreatureCommonAI::IsSummonNoBeAttacked()
{
	if (mMaster->CreatureKind() == CREATURE_MONSTER)
	{
		Monster* pMonster = dynamic_cast<Monster*>(mMaster);
		if (pMonster)
		{
			if (pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_SUMMON)
			{
				if (pMonster->GetMonsterFightType() == SUMMON_MONSTER_TYPE_CANNOT_BEATTACK_CANNOT_MOVE
						|| pMonster->GetMonsterFightType() == SUMMON_MONSTER_TYPE_CANNOT_BEATTACK_CAN_MOVE)
				{
					return true;
				}
			}
		}
	}
	return false;
}

bool CreatureCommonAI::IsSummonNoMoved()
{
	if (mMaster->CreatureKind() == CREATURE_MONSTER)
	{
		Monster* pMonster = dynamic_cast<Monster*>(mMaster);
		if (pMonster)
		{
			if (pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_SUMMON)
			{
				if (pMonster->GetMonsterFightType() == SUMMON_MONSTER_TYPE_CANNOT_BEATTACK_CANNOT_MOVE
						|| pMonster->GetMonsterFightType() == SUMMON_MONSTER_TYPE_CAN_BEATTACK_CANNOT_MOVE)
				{
					return true;
				}
			}
		}
	}
	return false;
}

behaviac::EBTStatus CreatureCommonAI::BiaoCheFinishPatrol()
{
	LogInfoFmtPrint("[logic] ++++++++++++CreatureCommonAI::BiaoCheFinishPatrol++++++++++++++++++");
	BiaoCheFinishPatrolEvent biaoche;
	biaoche.biaocheCid = mMaster->GetCid();
	biaoche.biaocheMasterCid = mOwnerCid;
	biaoche.sceneId = mMaster->GetSceneId();
	g_GetEvent()->FireExecute(EVENT_BIAOCHE_FINISH_PATROL, 0, CREATURE_MONSTER, &biaoche, sizeof(biaoche));
	return behaviac::EBTStatus::BT_SUCCESS;
}

behaviac::EBTStatus CreatureCommonAI::UnionBiaoCheFinishPatrol()
{
	LogInfoFmtPrint("[logic] ++++++++++++CreatureCommonAI::UnionBiaoCheFinishPatrol++++++++++++++++++");
	UnionBiaoCheFinishPatrolEvent unionBiaoChe;
	unionBiaoChe.biaocheCid = mMaster->GetCid();
	unionBiaoChe.biaocheUnionId = mUnionId;
	unionBiaoChe.sceneId = mMaster->GetSceneId();
	g_GetEvent()->FireExecute(EVENT_UNION_BIAOCHE_FINISH_PATROL, 0, CREATURE_MONSTER, &unionBiaoChe, sizeof(unionBiaoChe));
	return behaviac::EBTStatus::BT_SUCCESS;
}

behaviac::EBTStatus CreatureCommonAI::FindNearestEnemyInScene()
{
	if (mMaster->GetScene())
	{
		auto pMapPlayer = mMaster->GetScene()->GetAllPlayerInScene();
		for(auto it = pMapPlayer->begin(); it != pMapPlayer->end(); it++)
		{
			CharIDType cid = it->first;
			Creature* pTarget = mMaster->GetScene()->GetCreature(cid);
			if (pTarget)
			{
				mMaster->AddSeeNewCreature(pTarget);
			}
		}

		SET_UINT64 seeLst;
		mMaster->GetScene()->GetAllMonsterInScene(seeLst);
		for (auto it = seeLst.begin(); it != seeLst.end(); it++)
		{
			CharIDType cid = *it;
			Creature* pTarget = mMaster->GetScene()->GetCreature(cid);
			if (pTarget)
			{
				mMaster->AddSeeNewCreature(pTarget);
			}
		}
	}
	return behaviac::EBTStatus::BT_SUCCESS;
}

behaviac::EBTStatus CreatureCommonAI::SelectSkillFindNearestEnemy()
{
	if (SelectUsableSkill() == behaviac::EBTStatus::BT_FAILURE)
	{
		return behaviac::EBTStatus::BT_FAILURE;
	}

	float maxLength = this->AiGetSkillMaxAttackDict(mCurSkillId);
	if (mMaster->GetScene())
	{
		std::list<CharIDType> seeLst;
		mMaster->GetScene()->FindCreatureInCircle(seeLst, mMaster->GetPos(), maxLength);

		for(auto it = seeLst.begin(); it != seeLst.end(); it++)
		{
			if (*it != mMaster->GetCid())
			{
				mTargetCid = *it;
				return behaviac::EBTStatus::BT_SUCCESS;
			}
		}
	}

	return behaviac::EBTStatus::BT_FAILURE;
}

behaviac::EBTStatus CreatureCommonAI::FindNearestEnemy()
{
	if (mMaster->GetScene())
	{
		std::list<CharIDType> seeLst;
		mMaster->FindCreatureInScene(seeLst);
		for (auto it = seeLst.begin(); it != seeLst.end(); it++)
		{
			CharIDType cid = *it;
			Creature* pTarget = mMaster->GetScene()->GetCreature(cid);
			if (pTarget && pTarget->IsDead() == false)
			{
				mMaster->AddSeeNewCreature(pTarget);
			}
		}
	}
	return behaviac::EBTStatus::BT_SUCCESS;
}

behaviac::EBTStatus CreatureCommonAI::TrapTriggerEnemy()
{
	if (mMaster->GetScene() == nullptr || mMaster->CreatureKind() != CREATURE_MONSTER)
	{
		return behaviac::EBTStatus::BT_FAILURE;
	}

	Monster* pMonster = dynamic_cast<Monster*>(mMaster);
	if (pMonster == nullptr)
	{
		return behaviac::EBTStatus::BT_FAILURE;
	}

	SkillPart* pSkillPart = dynamic_cast<SkillPart*>(mMaster->GetPart(PART_SKILL));
	if (pSkillPart == nullptr)
	{
		return behaviac::EBTStatus::BT_FAILURE;
	}

	if (this->mCurSkillId <= 0)
	{
		return behaviac::EBTStatus::BT_FAILURE;
	}

	std::vector<CharIDType> vecTarget;
	int fightType = pMonster->GetMonsterFightType();
	std::list<CharIDType> seeLst;
	mMaster->FindCreatureInScene(seeLst);
	float fightSquare = mMaster->GetSightRange()*mMaster->GetSightRange();
	float minDict = fightSquare;
	Creature* pNearestTarget = nullptr;
	for (auto it = seeLst.begin(); it != seeLst.end(); it++)
	{
		CharIDType cid = *it;
		Creature* pTarget = mMaster->GetScene()->GetCreature(cid);

		if (pTarget == nullptr || pTarget->IsDead() || cid == mMaster->GetCid())
		{
			continue;
		}

		float dict = point2LengthSquare(mMaster->GetPos(), pTarget->GetPos());
		if (dict > fightSquare)
		{
			continue;
		}

		bool flag = false;
		if (fightType == TRAP_MONSTER_TYPE_WEEKLY_TRAP)
		{
			if (pSkillPart->IsCanBeAttackBySkill(mCurSkillId, pTarget->GetCid()))
			{
				flag = true;
			}
		}
		else if (fightType == TRAP_MONSTER_TYPE_TRIGGLE_TRAP)
		{
			if (pSkillPart->IsCanBeAttackBySkill(mCurSkillId, pTarget->GetCid()) && IsTargetInTrapAreas(pTarget))
			{
				flag = true;
			}
		}
		else if (fightType == TRAP_MONSTER_TYPE_NOMOVE_TRAP)
		{
			if (pSkillPart->IsCanBeAttackBySkill(mCurSkillId, pTarget->GetCid()))
			{
				flag = true;
			}
		}

		if (flag)
		{
			if (dict < minDict)
			{
				minDict = dict;
				pNearestTarget = pTarget;
			}
			vecTarget.push_back(cid);
		}
	}

	if (fightType == TRAP_MONSTER_TYPE_WEEKLY_TRAP)
	{
		pSkillPart->BeginCreatureUseSkill(mCurSkillId, vecTarget, mMaster->GetDir(), mMaster->GetPos());
		return behaviac::EBTStatus::BT_SUCCESS;
	}

	if (vecTarget.empty())
	{
		return behaviac::EBTStatus::BT_FAILURE;
	}
	else
	{
		if (pSkillPart->IsCanUseSkill(mCurSkillId, &vecTarget) == false)
		{
			return behaviac::EBTStatus::BT_FAILURE;
		}

		Point3<float> dir = mMaster->GetDir();
		if (pNearestTarget)
		{
			Point3<float> face = pNearestTarget->GetPos() - mMaster->GetPos();
			face.y = 0;
			float length = face.length();
			if (length != 0)
			{
				face = face / length;
				dir = face;
			}
		}

		if (pNearestTarget)
		{
			pSkillPart->BeginCreatureUseSkill(mCurSkillId, vecTarget, dir, pNearestTarget->GetPos());
		}
		else
		{
			pSkillPart->BeginCreatureUseSkill(mCurSkillId, vecTarget, dir, mMaster->GetPos());
		}

	}

	return behaviac::EBTStatus::BT_SUCCESS;
}

behaviac::EBTStatus CreatureCommonAI::NoBeAttackSummonUseSkill()
{
	if (mMaster->GetScene() == nullptr || mMaster->CreatureKind() != CREATURE_MONSTER)
		{
			return behaviac::EBTStatus::BT_FAILURE;
		}

		Monster* pMonster = dynamic_cast<Monster*>(mMaster);
		if (pMonster == nullptr || pMonster->GetParentMonsterType() != PARENT_MONSTER_TYPE_SUMMON)
		{
			return behaviac::EBTStatus::BT_FAILURE;
		}

		SkillPart* pSkillPart = dynamic_cast<SkillPart*>(mMaster->GetPart(PART_SKILL));
		if (pSkillPart == nullptr)
		{
			return behaviac::EBTStatus::BT_FAILURE;
		}

		if (this->mCurSkillId <= 0)
		{
			return behaviac::EBTStatus::BT_FAILURE;
		}

		float minAttack = AiGetSkillMinAttackDict(mCurSkillId);
		float maxAttackSquare = minAttack * minAttack;

		std::vector<CharIDType> vecTarget;
		std::list<CharIDType> seeLst;
		mMaster->FindCreatureInScene(seeLst);
		float fightSquare = mMaster->GetSightRange()*mMaster->GetSightRange();
		float minDict = fightSquare;
		Creature* pNearestTarget = nullptr;
		if (pMonster->GetMonsterType() == ENUM_MONSTER_TYPE_SPECIAL_SUMMON_FOR_OWNER_USE_SKILL)
		{
			CharIDType cid = pMonster->GetMonsterMasterCID();
			Creature* pTarget = mMaster->GetScene()->GetCreature(cid);

			if (pTarget != nullptr && !pTarget->IsDead() && cid != mMaster->GetCid())
			{
				float dict = point2LengthSquare(mMaster->GetPos(), pTarget->GetPos());
				if (dict < maxAttackSquare)
				{
					if (pSkillPart->IsCanBeAttackBySkill(mCurSkillId, pTarget->GetCid()))
					{
						if (dict < minDict)
						{
							minDict = dict;
							pNearestTarget = pTarget;
						}
						vecTarget.push_back(cid);
					}
				}
			}
		}
		else
		{
			for (auto it = seeLst.begin(); it != seeLst.end(); it++)
			{
				CharIDType cid = *it;
				Creature* pTarget = mMaster->GetScene()->GetCreature(cid);

				if (pTarget == nullptr || pTarget->IsDead() || cid == mMaster->GetCid())
				{
					continue;
				}

				float dict = point2LengthSquare(mMaster->GetPos(), pTarget->GetPos());
				if (dict > maxAttackSquare)
				{
					continue;
				}

				if (pSkillPart->IsCanBeAttackBySkill(mCurSkillId, pTarget->GetCid()))
				{
					if (dict < minDict)
					{
						minDict = dict;
						pNearestTarget = pTarget;
					}
					vecTarget.push_back(cid);
				}
			}
		}

		if (vecTarget.empty())
		{
			return behaviac::EBTStatus::BT_FAILURE;
		}
		else
		{
			if (pSkillPart->IsCanUseSkill(mCurSkillId, &vecTarget) == false)
			{
				return behaviac::EBTStatus::BT_FAILURE;
			}

			Point3<float> dir = mMaster->GetDir();
			if (pNearestTarget)
			{
				Point3<float> face = pNearestTarget->GetPos() - mMaster->GetPos();
				face.y = 0;
				float length = face.length();
				if (length != 0)
				{
					face = face / length;
					dir = face;
				}
			}

			if (pNearestTarget)
			{
				pSkillPart->BeginCreatureUseSkill(mCurSkillId, vecTarget, dir, pNearestTarget->GetPos());
			}
			else
			{
				pSkillPart->BeginCreatureUseSkill(mCurSkillId, vecTarget, dir, mMaster->GetPos());
			}

		}

		return behaviac::EBTStatus::BT_SUCCESS;
}

behaviac::EBTStatus CreatureCommonAI::UseMonsterTriggerEnemy()
{
	if (mMaster->GetScene() == nullptr || mMaster->CreatureKind() != CREATURE_MONSTER)
	{
		return behaviac::EBTStatus::BT_FAILURE;
	}

	Monster* pMonster = dynamic_cast<Monster*>(mMaster);
	if (pMonster == nullptr || pMonster->GetParentMonsterType() != PARENT_MONSTER_TYPE_CAN_USE_THING)
	{
		return behaviac::EBTStatus::BT_FAILURE;
	}

	SkillPart* pSkillPart = dynamic_cast<SkillPart*>(mMaster->GetPart(PART_SKILL));
	if (pSkillPart == nullptr)
	{
		return behaviac::EBTStatus::BT_FAILURE;
	}

	std::vector<uint32_t> vec;
	pSkillPart->GetMonsterCanUseSkillID(vec);
	if (vec.empty())
	{
		this->mCurSkillId = pSkillPart->GetNormalSkillID();
	}
	else
	{
		uint32_t index = Random(0, vec.size() - 1);
		this->mCurSkillId = vec[index];
	}

	if (this->mCurSkillId <= 0)
	{
		return behaviac::EBTStatus::BT_FAILURE;
	}

	std::vector<CharIDType> vecTarget;
	std::list<CharIDType> seeLst;
	mMaster->FindCreatureInScene(seeLst);
	float fightSquare = mMaster->GetSightRange()*mMaster->GetSightRange();
	float minDict = fightSquare;
	Creature* pNearestTarget = nullptr;

	for (auto it = seeLst.begin(); it != seeLst.end(); it++)
	{
		CharIDType cid = *it;
		Creature* pTarget = mMaster->GetScene()->GetCreature(cid);

		if (pTarget == nullptr || pTarget->IsDead() || cid == mMaster->GetCid())
		{
			continue;
		}

		float dict = point2LengthSquare(mMaster->GetPos(), pTarget->GetPos());
		if (dict > fightSquare)
		{
			continue;
		}

		if (!pSkillPart->IsCanBeAttackBySkill(mCurSkillId, pTarget->GetCid()))
		{
			continue;
		}

		if (dict < minDict)
		{
			minDict = dict;
			pNearestTarget = pTarget;
		}
		vecTarget.push_back(cid);
	}

	if (pSkillPart)
	{
		if (pSkillPart->IsCanUseSkill(mCurSkillId, &vecTarget) == false)
		{
			return behaviac::EBTStatus::BT_FAILURE;
		}

		Point3<float> dir = mMaster->GetDir();
		if (pNearestTarget)
		{
			Point3<float> face = pNearestTarget->GetPos() - mMaster->GetPos();
			face.y = 0;
			float length = face.length();
			if (length != 0)
			{
				face = face / length;
				dir = face;
			}
		}

		if (pNearestTarget)
		{
			pSkillPart->BeginCreatureUseSkill(mCurSkillId, vecTarget, dir, pNearestTarget->GetPos());
		}
		else
		{
			pSkillPart->BeginCreatureUseSkill(mCurSkillId, vecTarget, dir, mMaster->GetPos());
		}

	}

	return behaviac::EBTStatus::BT_SUCCESS;
}

behaviac::EBTStatus CreatureCommonAI::NoMoveBossUsingSpecialSkill()
{
	if (mMaster->GetScene() == nullptr || mMaster->CreatureKind() != CREATURE_MONSTER)
	{
		return behaviac::EBTStatus::BT_FAILURE;
	}

	Monster* pMonster = dynamic_cast<Monster*>(mMaster);
	if (pMonster == nullptr)
	{
		return behaviac::EBTStatus::BT_FAILURE;
	}

	SkillPart* pSkillPart = dynamic_cast<SkillPart*>(mMaster->GetPart(PART_SKILL));
	if (pSkillPart == nullptr)
	{
		return behaviac::EBTStatus::BT_FAILURE;
	}

	mCurSkillId = 0;
	const AiAiCfgInfo *pInfo = g_GetAiAiCfgTable()->GetAiAiCfgInfo(pMonster->GetMonsterInfo()->specialAI);
	if (pInfo)
	{
		std::vector<int> bossSkill;
		CommonApi::SplitStrToVecInt(pInfo->bossSkill, ",", &bossSkill);
		if (bossSkill.size() >= 2)
		{
			if (pSkillPart->AddSkill(bossSkill[0], 1))
				mCurSkillId = bossSkill[0];
		}
	}

	if (mCurSkillId == 0)
	{
		return behaviac::EBTStatus::BT_FAILURE;
	}

	Point3<float> monsterDir = pMonster->GetDir();

	std::vector<CharIDType> vecTarget;
	std::list<CharIDType> seeLst;
	mMaster->FindCreatureInScene(seeLst);

	for (auto it = seeLst.begin(); it != seeLst.end(); it++)
	{
		CharIDType cid = *it;
		Creature* pTarget = mMaster->GetScene()->GetCreature(cid);

		if (pTarget == nullptr || pTarget->IsDead() || cid == mMaster->GetCid())
		{
			continue;
		}

		if (!mMaster->IsFriendSide(pTarget))
		{
			vecTarget.push_back(cid);
		}
	}

	if (pSkillPart)
	{
		pSkillPart->BeginCreatureUseSkill(mCurSkillId, vecTarget, monsterDir, mMaster->GetPos());

		pMonster->SetDir(monsterDir);
	}

	return behaviac::EBTStatus::BT_SUCCESS;
}

behaviac::EBTStatus CreatureCommonAI::NoMoveBossTriggerNearestEnemy()
{
	if (mMaster->GetScene() == nullptr || mMaster->CreatureKind() != CREATURE_MONSTER)
	{
		return behaviac::EBTStatus::BT_FAILURE;
	}

	Monster* pMonster = dynamic_cast<Monster*>(mMaster);
	if (pMonster == nullptr)
	{
		return behaviac::EBTStatus::BT_FAILURE;
	}

	SkillPart* pSkillPart = dynamic_cast<SkillPart*>(mMaster->GetPart(PART_SKILL));
	if (pSkillPart == nullptr)
	{
		return behaviac::EBTStatus::BT_FAILURE;
	}

	std::vector<CharIDType> vecTarget;
	std::list<CharIDType> seeLst;
	mMaster->FindCreatureInScene(seeLst);
	float fightSquare = mMaster->GetSightRange()*mMaster->GetSightRange();
	float minDict = fightSquare;
	Creature* pNearestTarget = nullptr;

	for (auto it = seeLst.begin(); it != seeLst.end(); it++)
	{
		CharIDType cid = *it;
		Creature* pTarget = mMaster->GetScene()->GetCreature(cid);

		if (pTarget == nullptr || pTarget->IsDead() || cid == mMaster->GetCid())
		{
			continue;
		}

		float dict = point2LengthSquare(mMaster->GetPos(), pTarget->GetPos());
		if (dict > fightSquare)
		{
			continue;
		}

		if (!mMaster->IsFriendSide(pTarget))
		{
			if (dict < minDict)
			{
				minDict = dict;
				pNearestTarget = pTarget;
			}
			vecTarget.push_back(cid);
		}
	}

	if (vecTarget.empty())
	{
		return behaviac::EBTStatus::BT_FAILURE;
	}

	if (pNearestTarget)
	{
		mCurSkillId = AiGetNextSkillId(minDict);
	}
	else
	{
		mCurSkillId = AiGetNextSkillId();
	}

	const SkillCfg* pCfg = g_GetSkillMgr()->GetSkillCfg(mCurSkillId);
	if (pCfg == nullptr)
	{
		return behaviac::EBTStatus::BT_FAILURE;
	}

	if (pSkillPart)
	{
		if (pSkillPart->IsCanUseSkill(mCurSkillId, &vecTarget) == false)
		{
			return behaviac::EBTStatus::BT_FAILURE;
		}

		Point3<float> dir = mMaster->GetDir();
		if (pNearestTarget)
		{
			Point3<float> face = pNearestTarget->GetPos() - mMaster->GetPos();
			face.y = 0;
			float length = face.length();
			if (length != 0)
			{
				face = face / length;
				dir = face;
			}
		}

		if (pNearestTarget)
		{
			pSkillPart->BeginCreatureUseSkill(mCurSkillId, vecTarget, dir, pNearestTarget->GetPos());
		}
		else
		{
			pSkillPart->BeginCreatureUseSkill(mCurSkillId, vecTarget, dir, mMaster->GetPos());
		}

	}

	return behaviac::EBTStatus::BT_SUCCESS;
}

behaviac::EBTStatus CreatureCommonAI::TriggerNearestEnemy()
{
	if (mMaster->GetScene() == nullptr || mMaster->CreatureKind() != CREATURE_MONSTER)
	{
		return behaviac::EBTStatus::BT_FAILURE;
	}

	Monster* pMonster = dynamic_cast<Monster*>(mMaster);
	if (pMonster == nullptr || pMonster->GetParentMonsterType() != PARENT_MONSTER_TYPE_CAN_TRIGGER_THING)
	{
		return behaviac::EBTStatus::BT_FAILURE;
	}

	if (this->mCurSkillId <= 0)
	{
		return behaviac::EBTStatus::BT_FAILURE;
	}

	SkillPart* pSkillPart = dynamic_cast<SkillPart*>(mMaster->GetPart(PART_SKILL));
	if (pSkillPart == nullptr)
	{
		return behaviac::EBTStatus::BT_FAILURE;
	}

	std::vector<CharIDType> vecTarget;
	int fightType = pMonster->GetMonsterFightType();
	std::list<CharIDType> seeLst;
	mMaster->FindCreatureInScene(seeLst);
	float fightSquare = mMaster->GetSightRange()*mMaster->GetSightRange();
	float minDict = fightSquare;
	Creature* pNearestTarget = nullptr;

	for (auto it = seeLst.begin(); it != seeLst.end(); it++)
	{
		CharIDType cid = *it;
		Creature* pTarget = mMaster->GetScene()->GetCreature(cid);

		if (pTarget == nullptr || pTarget->IsDead() || cid == mMaster->GetCid())
		{
			continue;
		}

		float dict = point2LengthSquare(mMaster->GetPos(), pTarget->GetPos());
		if (dict > fightSquare)
		{
			continue;
		}

		bool flag = false;
		if (fightType == TRIGGLE_MONSTER_TYPE_TARGET_EVERYTHING)
		{
			if (pSkillPart->IsCanBeAttackBySkill(mCurSkillId, pTarget->GetCid())) //!m_pMaster->IsFriendSide(pTarget))
			{
				flag = true;
			}
		}
		else if (fightType == TRIGGLE_MONSTER_TYPE_TARGET_PLAYER)
		{
			if (pTarget->CreatureKind() == CREATURE_PLAYER && pSkillPart->IsCanBeAttackBySkill(mCurSkillId, pTarget->GetCid()))
			{
				flag = true;
			}
		}
		else if (fightType == TRIGGLE_MONSTER_TYPE_TARGET_MONSTER)
		{
			if (pTarget->CreatureKind() == CREATURE_MONSTER && pSkillPart->IsCanBeAttackBySkill(mCurSkillId, pTarget->GetCid()))
			{
				flag = true;
			}
		}
		else if (fightType == TRIGGLE_MONSTER_TYPE_TARGET_NPC)
		{
			if (pTarget->CreatureKind() == CREATURE_NPC && pSkillPart->IsCanBeAttackBySkill(mCurSkillId, pTarget->GetCid()))
			{
				flag = true;
			}
		}

		if (flag)
		{
			if (dict < minDict)
			{
				minDict = dict;
				pNearestTarget = pTarget;
			}
			vecTarget.push_back(cid);
		}
	}

	if (vecTarget.empty())
	{
		return behaviac::EBTStatus::BT_FAILURE;
	}

	if (pSkillPart)
	{
		if (pSkillPart->IsCanUseSkill(mCurSkillId, &vecTarget) == false)
		{
			return behaviac::EBTStatus::BT_FAILURE;
		}

		Point3<float> dir = mMaster->GetDir();
		if (pNearestTarget)
		{
			Point3<float> face = pNearestTarget->GetPos() - mMaster->GetPos();
			face.y = 0;
			float length = face.length();
			if (length != 0)
			{
				face = face / length;
				dir = face;
			}
		}

		if (pNearestTarget)
		{
			pSkillPart->BeginCreatureUseSkill(mCurSkillId, vecTarget, dir, pNearestTarget->GetPos());
		}
		else
		{
			pSkillPart->BeginCreatureUseSkill(mCurSkillId, vecTarget, dir, mMaster->GetPos());
		}

	}

	return behaviac::EBTStatus::BT_SUCCESS;
}

behaviac::EBTStatus CreatureCommonAI::KillSelf()
{
	mMaster->SetAttr(C_HP, 0, true);
	return behaviac::EBTStatus::BT_SUCCESS;
}

behaviac::EBTStatus CreatureCommonAI::StopAI()
{
	mAiEnable = false;
	return behaviac::EBTStatus::BT_SUCCESS;
}

behaviac::EBTStatus CreatureCommonAI::StopMove()
{
	mMaster->StopMove();
	return behaviac::EBTStatus::BT_SUCCESS;
}

bool CreatureCommonAI::IsTargetInArea(Creature* pCreature, uint32_t areaId)
{
	if (pCreature)
	{
		return g_GetMapLocationCfg()->InArea(areaId, pCreature->GetPos());
	}
	return false;
}

Creature*	CreatureCommonAI::GetTeamLeader()
{
	if (mNpcTeamId > 0)
	{
		return g_GetCreatureMgr()->FindTeamLeader(mMaster->GetSceneId(), mNpcTeamId);
	}
	return nullptr;
}

bool CreatureCommonAI::IsTargetInTrapAreas(Creature* pTarget)
{
	if (mMaster->CreatureKind() == CREATURE_MONSTER && pTarget)
	{
		Monster* pMonster = dynamic_cast<Monster*>(mMaster);
		if (pMonster)
		{
			std::vector<int> vecAreas;
			CommonApi::SplitStrToVecInt(pMonster->GetMonsterInfo()->trapArea, ",", &vecAreas);
			for(int i = 0; i < (int)vecAreas.size(); i++)
			{
				if (IsTargetInArea(pTarget, vecAreas[i]))
				{
					return true;
				}
			}
		}
	}
	return false;
}

bool CreatureCommonAI::IsSummonMonster()
{
	if (mMaster->CreatureKind() == CREATURE_MONSTER)
	{
		Monster* pMonster = dynamic_cast<Monster*>(mMaster);
		if (pMonster)
		{
			if (pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_SUMMON)
			{
				return true;
			}
		}
	}
	return false;
}

bool CreatureCommonAI::IsBiaocheMonster()
{
	if (mMaster->CreatureKind() == CREATURE_MONSTER)
	{
		Monster* pMonster = dynamic_cast<Monster*>(mMaster);
		if (pMonster)
		{
			if (pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_MOVE_BIAOCHE_MONSTER)
			{
				return true;
			}
		}
	}
	return false;
}

Point3<float> CreatureCommonAI::GetMoveSummonTargetPos()
{
	return mPatrolRandomPos.GetTargetPos();
}

void CreatureCommonAI::SetMoveSummonTargetPos(const Point3<float>& pos)
{
	mPatrolRandomPos.SetTargetPos(pos);
}

behaviac::EBTStatus CreatureCommonAI::SetFightStatus()
{
	if (HasPatrolPath())
	{
		if (mBFightStatus == false)
		{
			mHomePos = mMaster->GetPos();
		}
	}

	mBFightStatus = true;
	return behaviac::EBTStatus::BT_SUCCESS;
}

behaviac::EBTStatus CreatureCommonAI::ClearFightStatus()
{
	mBFightStatus = false;
	return behaviac::EBTStatus::BT_SUCCESS;
}

bool CreatureCommonAI::IsFightStatus()
{
	return mBFightStatus;
}

bool CreatureCommonAI::IsNpcTeamLeader()
{
	if (mMaster->CreatureKind() == CREATURE_NPC)
	{
		Npc* pNpc = dynamic_cast<Npc*>(mMaster);
		if (pNpc && pNpc->GetBattleInfo() && pNpc->GetBattleInfo()->npcTeam > 0)
		{
			return g_GetCreatureMgr()->IsTeamLeader(mMaster->GetSceneId(), pNpc->GetBattleInfo()->npcTeam, pNpc);
		}
	}
	return false;
}

bool CreatureCommonAI::IsInNpcTeam()
{
	if (mMaster->CreatureKind() == CREATURE_NPC)
	{
		Npc* pNpc = dynamic_cast<Npc*>(mMaster);
		if (pNpc && pNpc->GetBattleInfo() && pNpc->GetBattleInfo()->npcTeam > 0)
		{
			return true;
		}
	}
	return false;
}

bool CreatureCommonAI::IsMoveSummonReachTargetPos()
{
	return mPatrolRandomPos.IsReachTargetPos();
}

bool CreatureCommonAI::HasGroupSkills() const
{
	return !mGroupSkillIds.empty();
}

bool CreatureCommonAI::GroupSkillCanUse() const
{
	if (mGroupCdTime + mGroupCdInternal < g_GetGlobalServerTime()->Tick())
	{
		return true;
	}
	return false;
}

uint32_t CreatureCommonAI::GetRandomGroupSkillId() const
{
	if (mGroupSkillIds.size() > 0)
	{
		uint32_t index = Random(mGroupSkillIds.size());
		return mGroupSkillIds[index];
	}
	return 0;
}

bool CreatureCommonAI::IsNeedTeamDictTooFar()
{
	Creature* pTarget = mMaster->GetScene()->GetCreature(mFollowCid);
	if (pTarget == nullptr) return false;
	float dict = point2Length(mMaster->GetPos(), pTarget->GetPos());
	if (dict > 3.0f)
	{
		return true;
	}
	return false;
}

bool CreatureCommonAI::IsNeedTeamDictTooNear()
{
	Creature* pTarget = mMaster->GetScene()->GetCreature(mFollowCid);
	if (pTarget == nullptr) return false;
	float dict = point2Length(mMaster->GetPos(), pTarget->GetPos());
	if (dict < 1.50f)
	{
		return true;
	}
	return false;
}

bool CreatureCommonAI::IsNeedTeamDirTooNear()
{
	Creature* pTarget = mMaster->GetScene()->GetCreature(mFollowCid);
	if (pTarget == nullptr) return false;
	if (mMaster->GetDir().x * pTarget->GetDir().x +  mMaster->GetDir().y * pTarget->GetDir().y> 0)
	{
		return true;
	}
	return false;
}

behaviac::EBTStatus CreatureCommonAI::NpcTeamCountPatrolPos()
{
	Creature* pLeader = GetTeamLeader();
	if (pLeader == nullptr) return behaviac::EBTStatus::BT_FAILURE;

	if (pLeader->GetAiData()->HasHateListPlayer()) return behaviac::EBTStatus::BT_FAILURE;

	Creature* pTarget = mMaster->GetScene()->GetCreature(mFollowCid);
	if (pTarget == nullptr || pTarget->GetAiData() == nullptr) return behaviac::EBTStatus::BT_SUCCESS;

	if (mPatrolPath.IsMoveToTarget() != pTarget->GetAiData()->GetPatrolPath().IsMoveToTarget())
	{
		mPatrolPath.SetIsMoveToTarget(pTarget->GetAiData()->GetPatrolPath().IsMoveToTarget());
		if (mPatrolPath.GetPatrolType() == ENUM_MONSTER_PATROL_TYPE_LOOP_TRIP)
		{
			mPatrolPath.SetNextPatrolPathIndex(pTarget->GetAiData()->GetPatrolPath().GetNextPatrolPathIndex());
		}
	}

	if (mPatrolPath.IsMoveToTarget() || mPatrolPath.GetPatrolType() == ENUM_MONSTER_PATROL_TYPE_LOOP_TRIP)
	{
		if (mPatrolPath.GetNextPatrolPathIndex() > pTarget->GetAiData()->GetPatrolPath().GetNextPatrolPathIndex())
		{
			StopMove();
			return behaviac::EBTStatus::BT_FAILURE;
		}
		else if (mPatrolPath.GetNextPatrolPathIndex() == pTarget->GetAiData()->GetPatrolPath().GetNextPatrolPathIndex())
		{
			if (mPatrolPath.GetDictToNextPatrolPath() <= pTarget->GetAiData()->GetPatrolPath().GetDictToNextPatrolPath())
			{
				StopMove();
				return behaviac::EBTStatus::BT_FAILURE;
			}
		}
	}
	else
	{
		if (mPatrolPath.GetNextPatrolPathIndex() < pTarget->GetAiData()->GetPatrolPath().GetNextPatrolPathIndex())
		{
			StopMove();
			return behaviac::EBTStatus::BT_FAILURE;
		}
		else if (mPatrolPath.GetNextPatrolPathIndex() == pTarget->GetAiData()->GetPatrolPath().GetNextPatrolPathIndex())
		{
			if (mPatrolPath.GetDictToNextPatrolPath() <= pTarget->GetAiData()->GetPatrolPath().GetDictToNextPatrolPath())
			{
				StopMove();
				return behaviac::EBTStatus::BT_FAILURE;
			}
		}
	}

	return behaviac::EBTStatus::BT_SUCCESS;
}

behaviac::EBTStatus CreatureCommonAI::NpcTeamSetFollower()
{
	if (mMaster->CreatureKind() == CREATURE_NPC)
	{
		Npc* pNpc = dynamic_cast<Npc*>(mMaster);
		if (pNpc && mNpcTeamId > 0)
		{
			auto pFollow = g_GetCreatureMgr()->FindTeamFollower(mMaster->GetSceneId(), mNpcTeamId, pNpc);
			if (pFollow)
			{
				if (mFollowCid != pFollow->GetCid())
				{
					mFollowCid = pFollow->GetCid();
					if (!HasPatrolPath() && pFollow->GetAiData() && pFollow->GetAiData()->HasPatrolPath())
					{
						mPatrolPath.AddPatrolPath(pFollow->GetAiData()->GetPatrolPath().GetPatrolPath(), pFollow->GetAiData()->GetPatrolPath().GetPatrolType());
					}
				}
				return behaviac::EBTStatus::BT_SUCCESS;
			}
			else
			{
				mFollowCid = 0;
			}
		}
	}
	return behaviac::EBTStatus::BT_FAILURE;
}

behaviac::EBTStatus CreatureCommonAI::MoveSummonMove()
{
	if (GetMoveSummonTargetPos() == Point3<float>())
	{
		return behaviac::EBTStatus::BT_FAILURE;
	}

	MovePart* part = dynamic_cast<MovePart*>(mMaster->GetPart(PART_MOVE));
	if (part->IsMoving())
	{
		return behaviac::EBTStatus::BT_RUNNING;
	}
	else
	{
		if (IsMoveSummonReachTargetPos())
		{
			return behaviac::EBTStatus::BT_SUCCESS;
		}
		else
		{
			mMaster->MoveTo(GetMoveSummonTargetPos());
			return behaviac::EBTStatus::BT_RUNNING;
		}
	}
	return behaviac::EBTStatus::BT_FAILURE;
}

bool CreatureCommonAI::HasSummons()
{
	std::vector<Monster*> vec = mMaster->GetSummons();
	if (vec.empty())
	{
		return false;
	}
	return true;
}

bool CreatureCommonAI::IsNpcTeamLeaderHateListEmpty()
{
	Creature* pLeader = GetTeamLeader();
	if (pLeader && pLeader->GetAiData())
	{
		return pLeader->GetAiData()->IsHateListEmpty();
	}
	return false;
}

bool CreatureCommonAI::IsTargetInThePursuitRangeofNpcTeamLeader()
{
	Creature* pLeader = GetTeamLeader();
	if (pLeader && pLeader->GetAiData())
	{
		return pLeader->GetAiData()->IsTargetInThePursuitRange();
	}
	return false;
}

bool CreatureCommonAI::IsNpcTeamLeaderFightStats()
{
	Creature* pLeader = GetTeamLeader();
	if (pLeader && pLeader->GetAiData())
	{
		return pLeader->GetAiData()->IsFightStatus();
	}
	return false;
}

behaviac::EBTStatus CreatureCommonAI::SetTeamAttackTarget()
{
	Creature* pLeader = GetTeamLeader();
	if (pLeader && pLeader->GetAiData())
	{
		Creature* pTarget = pLeader->GetAiData()->GetTarget();
		if (pTarget && !pTarget->IsDead())
		{
			SetTargetCid(pTarget->GetCid());
			return behaviac::EBTStatus::BT_SUCCESS;
		}
	}

	SetTargetCid(0);
	return behaviac::EBTStatus::BT_FAILURE;
}

behaviac::EBTStatus CreatureCommonAI::RemoveTeamTarget()
{
	SetTargetCid(0);
	return behaviac::EBTStatus::BT_SUCCESS;
}

behaviac::EBTStatus CreatureCommonAI::TeamSetHome()
{
	MasterMove();
	mMaster->MoveTo(mHomePos);
	mMaster->AddBuffState(CREATURE_BUFF_STATE_WUDI);
	return behaviac::EBTStatus::BT_SUCCESS;
}

behaviac::EBTStatus CreatureCommonAI::TeamGoHome()
{
	MovePart* part = dynamic_cast<MovePart*>(mMaster->GetPart(PART_MOVE));
	if (part->IsMoving())
	{
		return behaviac::EBTStatus::BT_RUNNING;
	}
	else
	{
		MasterMove();
		float dict = point2LengthSquare(mHomePos, mMaster->GetPos());

		if (dict < 0.1)
		{
			mMaster->RemoveBuffState(CREATURE_BUFF_STATE_WUDI);
			ResetMonsterState();

			return behaviac::EBTStatus::BT_SUCCESS;
		}
		else
		{
			mMaster->MoveTo(mHomePos);
			return behaviac::EBTStatus::BT_RUNNING;
		}
	}
	return behaviac::EBTStatus::BT_FAILURE;
}

behaviac::EBTStatus CreatureCommonAI::ZhongShenBossMoveToSummon()
{
	if (IsMove())
	{
		return behaviac::EBTStatus::BT_SUCCESS;
	}

	std::vector<Monster*> vec = mMaster->GetSummons();
	if (vec.empty())
	{
		return behaviac::EBTStatus::BT_FAILURE;
	}

	float dict = point2LengthSquare(mMaster->GetPos(), vec[0]->GetPos());
	if (dict < 0.5)
	{
		return behaviac::EBTStatus::BT_SUCCESS;
	}
	else
	{
		mMaster->MoveTo(vec[0]->GetPos());
	}

	return behaviac::EBTStatus::BT_SUCCESS;
}

void CreatureCommonAI::AddHateTarget(CharIDType targetCid, int32_t hateValue, uint32_t damageValue)
{
	if (this->IsMonsterAttackMonster() == false)
	{
		return;
	}

	if (IsHateListEmpty())
	{
		if (mMaster->CreatureKind() == CREATURE_MONSTER)
		{
			Monster* pMonster = dynamic_cast<Monster*>(mMaster);
			if (pMonster && !pMonster->GetMonsterInfo()->onFightTrigger.empty())
			{
				std::vector<int32_t> vec;
				CommonApi::SplitStrToVecInt(pMonster->GetMonsterInfo()->onFightTrigger, ",", &vec);
				for(auto it = vec.begin(); it != vec.end(); it++)
				{
					g_GetEffectMgr()->OnEffect(pMonster, (EffectIDType)*it);
				}
			}
		}
	}
	if (this->IsMonsterAttackMonster() && GetIsStartTimer_Combat() == false)
	{
		StartTimerCombatStatus();
	}
	mHateList.AddHateTarget(targetCid, hateValue, damageValue);
}

void CreatureCommonAI::Update()
{
	if (GetAiEnable())
	{
		if (mMaster->IsDestory() || mMaster->IsDead() || mMaster->HasBuffStateNoAiControl())
		{
			return;
		}

		BEGIN_PROFILE("CreatureCommonAI::Update");

		if (mMaster->CreatureKind() == CREATURE_MONSTER)
		{
			BehaviacTreeRun();
		}
		else if (mMaster->CreatureKind() == CREATURE_NPC)
		{
			Npc* pNpc = dynamic_cast<Npc*>(mMaster);
			if (pNpc)
			{
				if (mMaster->BeenSeeByPlayer() || this->IsFightStatus())
				{
					if (this->mNpcTeamId <= 0)
					{
						if (this->IsHateListEmpty())
						{
							this->FindNearestEnemy();
						}
					}
					else
					{
						if (this->IsNpcTeamLeader() && !this->IsFightStatus())
						{
							if (this->IsHateListEmpty())
							{
								this->FindNearestEnemy();
							}
						}
					}
					BehaviacTreeRun();
				}
				else if (mMaster->GetScene() && mMaster->GetScene()->GetAllPlayerInScene()->empty() == false && pNpc->GetBattleInfo()->isAIWorkWhenNobody > 0)
				{
					if (this->mNpcTeamId <= 0)
					{
						if (this->IsHateListEmpty())
						{
							this->FindNearestEnemy();
						}
					}
					else
					{
						if (this->IsNpcTeamLeader() && !this->IsFightStatus())
						{
							if (this->IsHateListEmpty())
							{
								this->FindNearestEnemy();
							}
						}
					}
					BehaviacTreeRun();
				}
			}
		}
		else
		{
			BehaviacTreeRun();
		}
		END_PROFILE();
	}

}

void CreatureCommonAI::BehaviacTreeRun()
{
	if (GetIsBehavicTreeRun() == false)
	{
		SetIsBehavicTreeRun(true);
		btexec();
		SetIsBehavicTreeRun(false);
	}
}

void CreatureCommonAI::StartTimerAutoMonsterFindEnemyAI(int internal)
{
	StopTimerAutoMonsterFindEnemyAI();
#ifdef AI_MONSTER_VS_MONSTER
	SetAiInternalTime(internal);
	g_GetTimerAxis()->SetTimer(AI_TIME_AUTO_MONSTER_FIND_ENEMY, this->GetAiInternalTime(), this, INFINITY_CALL);
	SetIsStartTimer_AutoMonsterFindEnemyAI(true);
#else

	if (!mMaster->IsDead())
	{
		if (IsMonsterAutoAttack())
		{
			SetAiInternalTime(internal);
			g_GetTimerAxis()->SetTimer(AI_TIME_AUTO_MONSTER_FIND_ENEMY, this->GetAiInternalTime(), this, INFINITY_CALL);
			SetIsStartTimer_AutoMonsterFindEnemyAI(true);
		}
	}
#endif
}

void CreatureCommonAI::StopTimerAutoMonsterFindEnemyAI()
{
	if (GetIsStartTimer_AutoMonsterFindEnemyAI())
	{
		g_GetTimerAxis()->KillTimer(AI_TIME_AUTO_MONSTER_FIND_ENEMY, this);
	}
	SetIsStartTimer_AutoMonsterFindEnemyAI(false);
}

void CreatureCommonAI::OnHandleAutoMonsterFindEnemyAI()
{
	if (this->IsHateListEmpty())
	{
		FindNearestEnemy();
	}
}

void CreatureCommonAI::StartTimerRestStatus()
{
	StopTimerRestStatus();
	if (!mMaster->IsDead())
	{
		int restTime = GetRestWaitTime();
		int randTime = Random(restTime*0.5, restTime*1.5);

		SetAiInternalTime(randTime);
		BroadcastPlayIdle();
		g_GetTimerAxis()->SetTimer(AI_TIME_REST_STATUS, this->GetAiInternalTime(), this, 1);
		SetIsStartTimer_RestStatus(true);

		if (GetIsStartTimer_AutoMonsterFindEnemyAI() == false)
		{
			StartTimerAutoMonsterFindEnemyAI();
		}
	}
}

void CreatureCommonAI::StopTimerRestStatus()
{
	if (GetIsStartTimer_RestStatus())
	{
		g_GetTimerAxis()->KillTimer(AI_TIME_REST_STATUS, this);
	}
	SetIsStartTimer_RestStatus(false);
}

void CreatureCommonAI::OnHandleRestStatus()
{
	SetIsStartTimer_RestStatus(false);
	Monster* pMonster = dynamic_cast<Monster*>(mMaster);
	if (pMonster)
	{
		if (pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_MONSTER)
		{
			if (this->HasPatrolPath() || this->HasActionRange())
			{
				StartTimerPatrolStatus();
			}
			else
			{
				StartTimerRestStatus();
			}
		}
		else
		{
			StartTimerRestStatus();
		}
	}
}

void CreatureCommonAI::StartTimerPatrolStatus()
{
	StopTimerPatrolStatus();
	if (!mMaster->IsDead())
	{
		SetAiInternalTime(PATROL_STATUS_TIME);
		g_GetTimerAxis()->SetTimer(AI_TIME_PATROL_STATUS, this->GetAiInternalTime(), this);
		SetIsStartTimer_PatrolStatus(true);

		if (GetIsStartTimer_AutoMonsterFindEnemyAI() == false)
		{
			StartTimerAutoMonsterFindEnemyAI();
		}

		if(this->HasPatrolPath())
		{
			MoveToNextPatrolPath();
		}
		else if (this->HasActionRange())
		{
			MoveToNextRandomPos();
		}
	}
}

void CreatureCommonAI::StopTimerPatrolStatus()
{
	if (GetIsStartTimer_PatrolStatus())
	{
		g_GetTimerAxis()->KillTimer(AI_TIME_PATROL_STATUS, this);
	}
	SetIsStartTimer_PatrolStatus(false);
}

void CreatureCommonAI::OnHandlePatrolStatus()
{
	if (this->IsMove())
	{
		return;
	}

	StopTimerPatrolStatus();

	if (mMaster->CreatureKind() == CREATURE_NPC)
	{
		if (IsInNpcTeam())
		{
			if (IsNpcTeamLeader())
			{
				if (mPatrolPath.IsReachNextPatrolPath() && mPatrolPath.GetNextPatrolPathIndex() == 0)
				{
					if (mNpcTeamId > 0)
					{
						g_GetGeneralCreatureRefMgr()->UpdateNpcTeamDead(mMaster->GetSceneId(), g_GetGlobalServerTime()->Tick(), mNpcTeamId);
					}
				}
				if (IsHateListEmpty() && !IsFightStatus())
				{
					MoveToNextPatrolPath();
				}
			}
			else
			{
				if (IsNpcTeamLeaderHateListEmpty() && !IsFightStatus() && !IsNpcTeamLeaderFightStats())
				{
					NpcTeamSetFollower();
					NpcTeamMoveToPatrolPath();
				}
			}
		}
	}

	if (mMaster->CreatureKind() == CREATURE_MONSTER)
	{
		Monster* pMonster = dynamic_cast<Monster*>(mMaster);
		if (pMonster)
		{
			if (GetIsStartTimer_Combat() == false && GetIsStartTimer_UseSkill() == false)
			{
				if (pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_MONSTER
						|| pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_TA)
				{
					if (mIsAIWorkWhenNobody > 0)
					{
						if (pMonster->GetScene() && !pMonster->GetScene()->GetAllPlayerInScene()->empty())
						{
							StartTimerRestStatus();
							return;
						}
					}

					if (mMaster->BeenSeeByPlayer())
					{
						StartTimerRestStatus();
						return;
					}
				}
			}
			else
			{
				OnHandleCombatStatus();
			}
		}
	}
}

void CreatureCommonAI::StartTimerCombatStatus()
{
	if (!mMaster->IsDead())
	{
		if (GetIsStartTimer_Combat() == false)
		{
			KillAllTimerNoCombatStatus();
			//StartTimerAutoMonsterFindEnemyAI(AUTO_MONSTER_FIND_ENEMY_TIME_IN_COMBAT);
			this->SetAiInternalTime(MIDDLE_AI);
			g_GetTimerAxis()->SetTimer(AI_TIME_COMBAT, this->GetAiInternalTime(), this, INFINITY_CALL);
			SetIsStartTimer_Combat(true);

			OnHandleCombatStatus();
		}
	}
}

void CreatureCommonAI::StopTimerCombatStatus()
{
	if (GetIsStartTimer_Combat())
	{
		g_GetTimerAxis()->KillTimer(AI_TIME_COMBAT, this);
	}
	SetIsStartTimer_Combat(false);
}

void CreatureCommonAI::OnHandleCombatStatus()
{
	Update();
}

void CreatureCommonAI::StartTimerUseSkill(float t)
{
	if (mMaster->CreatureKind() == CREATURE_MONSTER)
	{
		Monster* pMonster = dynamic_cast<Monster*>(mMaster);
		if (pMonster)
		{
			if (pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_BOSS_ZHONGSHEN)
			{
				this->SetAiInternalTime((int)t);
				g_GetTimerAxis()->SetTimer(AI_TIME_USE_SKILL, this->GetAiInternalTime(), this, 1);
				SetIsStartTimer_UseSkill(true);
				return;
			}
		}
	}

	StopTimerCombatStatus();
	StopTimerUseSkill();

	this->SetAiInternalTime((int)t);
	g_GetTimerAxis()->SetTimer(AI_TIME_USE_SKILL, this->GetAiInternalTime(), this, 1);
	SetIsStartTimer_UseSkill(true);
}

void CreatureCommonAI::StopTimerUseSkill()
{
	if (GetIsStartTimer_UseSkill())
	{
		g_GetTimerAxis()->KillTimer(AI_TIME_USE_SKILL, this);
	}
	SetIsStartTimer_UseSkill(false);
}

void CreatureCommonAI::OnHandleUseSkill()
{
	SetIsStartTimer_UseSkill(false);
	StartTimerCombatStatus();
}

void CreatureCommonAI::KillAllTimerNoCombatStatus()
{
	StopTimerAutoMonsterFindEnemyAI();
	StopTimerRestStatus();
	StopTimerPatrolStatus();
}

behaviac::EBTStatus CreatureCommonAI::HandleCommonSpecialSkills()
{
	if (this->HasSpecialAI() && this->HasHpStateNoTrigger())
	{
		GetHpState().HandleTriggerHpState();
		return behaviac::EBTStatus::BT_SUCCESS;
	}
	return behaviac::EBTStatus::BT_FAILURE;
}
